Why Do We Need Extensions?

You need extensions because they save you time from re-creating the same thing over and over again. Don’t you find it tiring sometimes that you have to type it over and over again?

Corner Radius

Most of the design you see now is either corner radius, shadow, border line or even rounded. Here’s the code:

extension UIView {
  func addCornerRadius(_ radius: CGFloat = 5) {
      layer.cornerRadius = radius
      layer.masksToBounds = true
  }
}

Example

The default value of the corner radius is always 5, but if you need something other than 4, you can just plug in any number. In the following example, you will use 16.

class ViewController: UIViewController {
    @IBOutlet weak var parentView: UIView!
    override func viewDidLoad() {
        super.viewDidLoad()
        parentView.backgroundColor = .blue
        parentView.addCornerRadius(16)
    }
}

Border Line

This piece of code will add a border line with an adjustable width. You may choose the type of color you would like the border to be.

extension UIView {
	func addBorderLine(width: CGFloat = 1, color: UIColor) {
        layer.borderWidth = width
        layer.borderColor = color.cgColor
    }
}

Example

As usual, the default value of the width is 1.0, but you could definitely play around with the number. Here I am setting the width to 2.0.

parentView.addBorderLine(width: 2.0, color: .blue)

You could even use addCornerRadius and then addBorderLine. This is the result of the combination effect. Such a beauty.

parentView.addCornerRadius(16)
parentView.addBorderLine(width: 2.0, color: .blue)

Round

In order for a view to be completely round, the width and the height need to match each other. If it doesn’t, you will probably see some capsule shape or weird-looking shape. Here’s the code:

extension UIView {
    func makeRounded() {
        layer.masksToBounds = false
        layer.cornerRadius = self.frame.height / 2
        clipsToBounds = true
    }
}

Example

This line of code will make a round shape.

parentView.makeRounded()

Shadow

This is probably the most used design everywhere on the app but definitely use it sparingly as it does impact the performance of the app.

extension UIView {    
    func addShadow(
       cornerRadius: CGFloat = 16,
       shadowColor: UIColor = UIColor(white: 0.0, alpha: 0.5),
       shadowOffset: CGSize = CGSize(width: 0.0, height: 3.0),
       shadowOpacity: Float = 0.3,
       shadowRadius: CGFloat = 5) {

          layer.cornerRadius = cornerRadius
          layer.shadowColor = shadowColor.cgColor
          layer.shadowOffset = shadowOffset
          layer.shadowOpacity = shadowOpacity
          layer.shadowRadius = shadowRadius
    }
}

Example

You probably see why it was the most used because it definitely changes the appearance of the app. It makes the app even more appealing. You will have to tweak the shadowOffset, shadowOpacity, shadowRadius and shadowColor to meet your designer’s standard.

parentView.addShadow()

Color

Sometimes, you can’t find the color on Xcode because designers use hex codes they randomly pick. The following code will help with that.

extension UIColor {
    convenience init(hexFromString:String, alpha:CGFloat = 1.0) {
        var cString:String = hexFromString.trimmingCharacters(in: .whitespacesAndNewlines).uppercased()
        var rgbValue:UInt32 = 10066329 //color #999999 if string has wrong format
        if (cString.hasPrefix("#")) {
            cString.remove(at: cString.startIndex)
        }
        if ((cString.count) == 6) {
            Scanner(string: cString).scanHexInt32(&rgbValue)
        }
        self.init(
            red: CGFloat((rgbValue & 0xFF0000) >> 16) / 255.0,
            green: CGFloat((rgbValue & 0x00FF00) >> 8) / 255.0,
            blue: CGFloat(rgbValue & 0x0000FF) / 255.0,
            alpha: alpha
        )
    }
    convenience init(red: Int, green: Int, blue: Int) {
        assert(red >= 0 && red <= 255, "Invalid red component")
        assert(green >= 0 && green <= 255, "Invalid green component")
        assert(blue >= 0 && blue <= 255, "Invalid blue component")
        self.init(red: CGFloat(red) / 255.0, green: CGFloat(green) / 255.0, blue: CGFloat(blue) / 255.0, alpha: 1.0)
    }
    convenience init(red: Int, green: Int, blue: Int, reqAlpha: CGFloat) {
        assert(red >= 0 && red <= 255, "Invalid red component")
        assert(green >= 0 && green <= 255, "Invalid green component")
        assert(blue >= 0 && blue <= 255, "Invalid blue component")
        self.init(red: CGFloat(red) / 255.0, green: CGFloat(green) / 255.0, blue: CGFloat(blue) / 255.0, alpha: reqAlpha)
    }
}

Example

You can add a hex code to get the kind of color you need.

parentView.backgroundColor = UIColor.init(hexFromString: "#7dbf0d")

Date

If your apps deal with dates, you probably will need to deal with many different kinds of formats of dates. With the code below, you are getting a String type instead of a Date.

extension Date {
    func getCurrentDate(_ format: String = "dd/MM/yyyy HH:mm:ss") -> String {
        let dateFormatter = DateFormatter()
        dateFormatter.dateFormat = format
        dateFormatter.timeZone = .current
        return dateFormatter.string(from: Date())
    }
}

Example

You could create a Label and instantiate Date to utilise the extension using the following code:

dateLabel.text = Date().getCurrentDate()

This result uses the format: dd/MM/yyyy HH:mm:ss. It looks like: 27/01/2021 09:04:55

If you need something else, you could change the format. Next, you will see an example of dd-MM-yyyy. Do keep in mind that the letter is according to its standard or you will get something else. It looks like: 27-01-2021


Make a view the same size as the superview

public extension UIView {
    public func fillSuperview() {
        guard let superview = self.superview else { return }
        translatesAutoresizingMaskIntoConstraints = superview.translatesAutoresizingMaskIntoConstraints
        if translatesAutoresizingMaskIntoConstraints {
            autoresizingMask = [.flexibleWidth, .flexibleHeight]
            frame = superview.bounds
        } else {
            topAnchor.constraint(equalTo: superview.topAnchor).isActive = true
            bottomAnchor.constraint(equalTo: superview.bottomAnchor).isActive = true
            leftAnchor.constraint(equalTo: superview.leftAnchor).isActive = true
            rightAnchor.constraint(equalTo: superview.rightAnchor).isActive = true
        }
    }
}

Example

superView.addSubview(view)
view.fillSuperview()

Get a view controller which has the view

public extension UIView {
    public var viewController: UIViewController? {
        var parent: UIResponder? = self
        while parent != nil {
            parent = parent?.next
            if let viewController = parent as? UIViewController {
                return viewController
            }
        }
        return nil
    }
}
view.viewController

Remove the same value from the array

public extension Array where Element: Hashable {
    public mutating func unify() {
        self = unified()
    }
}

public extension Collection where Element: Hashable {
    public func unified() -> [Element] {
        return Array(Set(self))
    }
}
let array = [1, 2, 3, 3, 2, 1, 4]
array.unify() // [1, 2, 3, 4]

Thank you for reading.