Skip to content

Instantly share code, notes, and snippets.

@alexpaul
Last active March 1, 2023 20:55
Show Gist options
  • Save alexpaul/978c561846b0c619ba7b01b1cfb0d9e7 to your computer and use it in GitHub Desktop.
Save alexpaul/978c561846b0c619ba7b01b1cfb0d9e7 to your computer and use it in GitHub Desktop.
Custom delegation. Protocol.

Delegates: You use delegates to interact with Cocoa objects that inform you of events in an app.
Apple docs - delegation

// Object A
class ViewController: UIViewController {
  override func viewDidLoad() {
    super.viewDidLoad()
  }
}

extension ViewController: UICollectionViewDataSource {
  func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
    return 50
  }
  func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    // step 4: custom delegation - we need a reference to the object we will need notification from, here it is an instance of the ItemCell
    guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "itemCell", for: indexPath) as? ItemCell else {
      fatalError("could not downcast to ItemCell")
    }
    // step 5: custom delegation - like in UITableView we need to set the delegate property, here we are setting self
    cell.delegate = self
    return cell
  }
}

// step 6: custom delegation - we need to conform to the ItemCellDelegage protocol and implement any required methods, properties or initializers
extension ViewController: ItemCellDelegate {
  func didLongPress(_ itemCell: ItemCell) {
    // show action sheet to user e.g delete action, share photo action, cancel action
  }
}
// Object B
// step 1: custom delegation - define a protocol and add methods, initializer, properties as needed
protocol ItemCellDelegate: AnyObject {
  func didLongPress(_ itemCell: ItemCell)
}

class ItemCell: UICollectionViewCell {
  // step 2: custom delegation - declare a property that will be a weak reference to the delegate object e.g ViewController in this case
  weak var delegate: ItemCellDelegate?
  
  func longPressAction() {
    // step 3: custom delegation - use the delegate property to update the delegate object about necessary updates, such as here the user long presses on a cell
    delegate?.didLongPress(self)
  }
}
 
 1. Use a protocol and add the required methods needed by the delegate e.g numberOfRows in 
 UITableViewDataSource. The protocol needs to inherit from AnyObject as it needs to ONLY work with 
 class objects. Why? Object B need to have a weak reference to Object A and only classes hold references.
 
 2. Declare a variable which will be a weak reference to Object A. This variable will be an optional as
 its not guaranteed that the delegate is set when Object A is instantiated.
 
 3. Use the delegate instance wherever you need to notify the delegate object of a change.
 
 4. Create an instance of Object B.
 
 5. Set the delegate property of Object B.
 
 6. Conform and implement the required protocol methods of Object B. 
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment