iOS Development Improvements/Tricks using the power of Extensions

Jul 19, 2016

Category

Author

I’m listing out few small improvements/tricks which can help you along your development cycle. Feel free to suggest your ways, I would love to add them to this list.

Notifications Naming

Name your notifications with bundle name prefixed to it. It will always help you avoid any name conflicts arising later:

enum Notification {
  static let NotificationOne    = "com.myapp." + "NotificationOne"
  static let NotificationTwo    = "com.myapp." + "NotificationTwo"
  static let NotificationThree  = "com.myapp." + "NotificationThree"
  static let NotificationFour   = "com.myapp." + "NotificationFour"
}

View Controller Easy Access

Add methods in UIViewController & UIStoryboard extensions to easily access and initiate VCs:

Don’t forget to add identifier in Storyboards’ view controllers.

extension UIViewController { 
  static func onboardingVC() -> OnboardingVC { 
    let identifier = String(describing: OnboardingVC.self) 
     
    return UIStoryboard.onboarding().instantiateViewController(
           withIdentifier: identifier) as! OnboardingVC 
  } 
} 

extension UIStoryboard { 
  static func onboarding() -> UIStoryboard { 
    return UIStoryboard(name: "Onboarding", bundle: nil) 
  }
} 

let onboardingController = UIViewController.onboardingVC()

Add Color extension to extrapolate color while animation

Add method to calculate intermediate color while animating between two colors. Use Case: if user spans his finger and you want to animate a color according to the span position.

toRGBAComponents() toHSLAComponents()

(these can be found in this library, which you can write your own)

extension UIColor {
  class func intermediateColor(fraction: CGFloat, 
                               initialColor: UIColor, 
                               finalColor: UIColor) -> UIColor {

    let initialRGBA = initialColor.toRGBAComponents()
    let finalRGBA = finalColor.toRGBAComponents()
    
    let redDiff     = (finalRGBA.r - initialRGBA.r)
    let greenDiff   = (finalRGBA.g - initialRGBA.g)
    let blueDiff    = (finalRGBA.b - initialRGBA.b)
    let alphaDiff   = (finalRGBA.a - initialRGBA.a)

    let red     = fraction * redDiff    + initialRGBA.r
    let green   = fraction * greenDiff  + initialRGBA.g
    let blue    = fraction * blueDiff   + initialRGBA.b
    let alpha   = fraction * alphaDiff  + initialRGBA.a

    return UIColor(red: red, green: green, blue: blue, alpha: alpha)
  }
}

//Set Color according to the position
let fractionMovement = CGFloat(userHandPositionX / finalPositionX)
view.backgroundColor = UIColor.intermediateColor(
                               fraction: fractionMovement,
                               initialColor: UIColor.green,
                               finalColor: UIColor.blue)

A similar function for HSLA can also be written:

class func intermediateHSLAColor(fraction: CGFloat, 
                                 initialColor: UIColor, 
                                 finalColor: UIColor) -> UIColor {

  let initialHSLA = initialColor.toHSLAComponents()
  let finalHSLA = finalColor.toHSLAComponents()

  let hueDiff         = (finalHSLA.h - initialHSLA.h)
  let saturationDiff  = (finalHSLA.s - initialHSLA.s)
  let luminosityDiff  = (finalHSLA.l - initialHSLA.l)
  let alphaDiff       = (finalHSLA.a - initialHSLA.a)

  let hue         = fraction * hueDiff        + initialHSLA.h
  let saturation  = fraction * saturationDiff + initialHSLA.s
  let lightness   = fraction * luminosityDiff + initialHSLA.l
  let alpha       = fraction * alphaDiff      + initialHSLA.a

  return UIColor(hue: hue, saturation: saturation, brightness:
                 lightness, alpha: alpha)
}

Present simple dialogs with in & out animations

Can be used for anything: logout confirmations, network activity alerts, capture user context dialogs etc.:

extension UIView {
    func presentWithForwardAnimation() {
        self.alpha = 0
        self.transform = CGAffineTransformMakeScale(0.8, 0.8)
        UIView.animateWithDuration(0.3) {
            self.transform = CGAffineTransformIdentity
            self.alpha = 1
        }
    }

    func dismissWithBackwardAnimation() {
        self.alpha = 1
        UIView.animateWithDuration(0.3, animations: {
            self.transform = CGAffineTransformMakeScale(0.8, 0.8)
            self.alpha = 0
        }) { (completed) in
            self.transform = CGAffineTransformIdentity
        }
    }
}

//Call to animate
animateView.presentWithForwardAnimation()

Adding day suffix for a particular day

Like Sept 12th21st of Jan etc.:

extension NSDate {
    func daySuffix() -> String {
        let calendar = NSCalendar.currentCalendar()
        let dayOfMonth = calendar.component(.Day, fromDate: self)
        switch dayOfMonth {
        case 1, 21, 31: return "st"
        case 2, 22: return "nd"
        case 3, 23: return "rd"
        default: return "th"
        }
    }
}

[UPDATE]

Recently came across this:

Add Cancel action to your alert controller:

extension UIAlertController {
    func addCancelAction() {
        let cancelAction = UIAlertAction(title: "Cancel", 
                                         style: .cancel, 
                                         handler: nil)
        addAction(cancelAction)
    }
}

let alertController = UIAlertController(title: "Alert", 
                                        message: "This is an alert", 
                                        preferredStyle: .alert)
alertController.addCancelAction()


Wrapping up: These small additions can really improve and ease development. I always carry these, along with many more, in my projects. I don’t like to include full Pods to get laundry list of such functions, I only import what is needed.