I ❤ Swift [Part 1] – UIViewController & Extensions

UIViewController & Extensions

What are Extensions?

Extensions add new functionality to an existing class, structure, enumeration, or protocol type. This includes the ability to extend types for which you do not have access to the original source code (known as retroactive modeling). Extensions are similar to categories in Objective-C. (Unlike Objective-C categories, Swift extensions do not have names.)

Using extensions the right way can improve your code organization dramatically. I will show how you can improve the code organization in your UIViewController classes and promise that you will use this approach all the time. Let’s start!

UIViewController & Extensions

UIViewController classes can contain a lot of code which can lead to a big and messy file. That is why we need to organize our code properly, by splitting it into separate extension blocks. You can add an infinite number of extensions in your file, but I will show you few examples how I use it.

NOTE: I have added a file at the end of this story (had to put it there as it was too long) which contains a simple code presentation for what you are about to read.
  • class block – here I declare variables (both fileprivate and public), outlets, override methods, lifecycle methods (viewDidLoad(), viewWillAppear(), etc.), and also internal methods.
  • private extension – this is the first and most common extension I create in each controller. It contains all the methods, actions, events that need to stay private. So instead of adding the private keyword before each method, Swift enables you to keep everything under the same block.
  • protocol extensions – if you ever need to implement delegate methods in your controller this is the best way to do it. Let’s say you need to implement UICollectionView inside a controller. That means you will need UICollectionViewDelegate, UICollectionViewDataSource and UICollectionViewDelegateFlowLayout extensions. Just create an extension for each protocol, and add the methods you need (see Gist example below).
  • MARK:// – is a simple directive that helps us organize our implementation code better (known as #pragma mark in Objective-C). Add mark above each extension describing what it does. That way your file will look like it’s split into “sections”.

This was Part 1 of the I ❤ Swift stories where I was explaining about the UIViewController & Extensions combination. Stay tuned for more! 🙂
Like and share with others if you found this story helpful so it can help others as well.

 

import UIKit

class ViewController: UIViewController {
    
    //MARK: Private Properties
    @IBOutlet fileprivate weak var titleLbl: UILabel!
    @IBOutlet fileprivate weak var actionBtn: UIButton!
    @IBOutlet fileprivate weak var collectionView: UICollectionView!
        
    //MARK: Internal Properties
    var title: String! 
    
    override func viewDidLoad() {
        super.viewDidLoad()
        setupUI()
    }
}

//MARK: Private extension - used to store private methods 
private extension ViewController{
    /* do any UI related stuff here */
    func setupUI(){
      self.title = "Some Title"
    }

    /* keep your actions in this block as well */        
    @IBAction func someAction(btn: UIButton){
      
    }    
}

//MARK: UICollectionViewDelegate 
extension ViewController: UICollectionViewDelegate{
    
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return 10
    }

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! CustomCell
        return cell
    }
}

//MARK: UICollectionViewDataSource 
extension ViewController: UICollectionViewDataSource{
    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
        
    }
}

//MARK: UICollectionViewDelegateFlowLayout 
extension ViewController: UICollectionViewDelegateFlowLayout{
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
        return collectionView.frame.size
    }
}

//MARK: SomeCustomDelegate 
extension ViewController: SomeCustomDelegate{
    func customDelegateMethod() {

    }
}

Recommended for you: Add separator on Int using NumberFormatter

Leave a Reply

Your email address will not be published. Required fields are marked *