Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Delegate Chaining Workaround

Delegate Chaining Workaround

Assume, you have a view controller hierarchy A, B, C and D, in some cases, you would like to access A from D. In typical strategy in iOS, you may provide numbers of delegate to navigate to A from D. I called it delegate chaining. This slide introduces you alternative way by using responder chain to access A from D.

79874cedccd1cf5baa8cb264b5091ee6?s=128

codelynx

October 30, 2020
Tweet

Transcript

  1. Delegate Chaining Workaround October 2010 Kaz Yoshikawa

  2. About me

  3. Kaz Yoshikawa • Electricwoods LLC ୅ද / Digital Lynx Systems

    Inc. ෭୅ද • e-mail: kyoshikawa@electricwoods.com • twitter: @codelynx1 • Working History • Adobe Systems (Tokyo) • Lionbridge (Tokyo) • Quark (Tokyo / Denver) • Hummingbird Communications (Mt. View, USA) • Fact International (Vancouver, Canada) • Perle Systems (Toronto, Canada), etc.
  4. What is Delegate Chaining?

  5. Delegate Chaining Primary VC Secondary VC Primary VC Secondary VC

    Tertiary VC Quaternary VC Delegate Delegate Delegate Delegate • Simple delegate: • Chain of delegates: Method Invocation
  6. protocol SecondaryViewControllerDelegate: AnyObject { func save() } class PrimaryViewController: UIViewController,

    SecondaryViewControllerDelegate { func save() { // save } } class SecondaryViewController: UIViewController { weak var delegate: SecondaryViewControllerDelegate? @IBAction func save(_ sender: UIButton) { self.delegate?.save() } } Simple Delegate
  7. Delegate Chaining class PrimaryViewController: UIViewController, SecondaryViewControllerDelegate { func save() {

    // save } } class SecondaryViewController: UIViewController, TertiaryViewControllerDelegate { weak var delegate: SecondaryViewControllerDelegate? func save() { self.delegate?.save() } } class TertiaryViewController: UIViewController, QuaternaryViewControllerDelegate { weak var delegate: TertiaryViewController? func save() { self.delegate?.save() } } class QuaternaryViewController: UIViewController { weak var delegate: QuaternaryViewControllerDelegate? @IBAction func save(_ sender: UIButton) { self.delegate?.save() } }
  8. Using UIResponder chain extension UIResponder { func findResponder<T>() -> T?

    { var responder = self.next while responder != nil { if let candidate = responder as? T { return candidate } responder = responder!.next } return nil } }
  9. protocol SaveProtocol: AnyObject { func save() } class PrimaryViewController :

    UIViewController, SaveProtocol { // snip func save() { print("Saved !!") } } // snip class QuaternaryViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() self.save() } func save() { if let saver = self.findResponder() as SaveProtocol? { saver.save() } } } Provide a Protocol
  10. Don’t extension UIResponder { func findResponder<T: UIResponder>() -> T? {

    var responder = self.next while responder != nil { if let candidate = responder as? T { return candidate } responder = responder!.next } return nil } }
  11. Sample Code •https://gist.github.com/codelynx/ 11f1fc1dc8a0de679c05dc88016a2480

  12. Wrap Up • You may avoid making delegate chain by

    following its responder chain • Don’t abuse
  13. fin