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

Delegate Chaining Workaround

codelynx
October 30, 2020

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.

codelynx

October 30, 2020
Tweet

More Decks by codelynx

Other Decks in Programming

Transcript

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

    Inc. ෭୅ද • e-mail: [email protected] • 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.
  2. 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
  3. 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
  4. 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() } }
  5. 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 } }
  6. 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
  7. 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 } }
  8. Wrap Up • You may avoid making delegate chain by

    following its responder chain • Don’t abuse