Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Protocol delegate between view before navigation stack

View1 segues to Navigation Controller - View2 segues to View3

I am trying to create protocol delegate from View3 to View1

In View1

class NormalUser: UIViewController, NormalUserDelegate {

    @objc func showAddressView() {
        addressView.isHidden = false
    }

    override func viewDidLoad() {
        super.viewDidLoad()

        if let conn = self.storyboard?.instantiateViewController(withIdentifier: "View") as? View
        {
            conn.delegate = self
        }
    }
}

In View3

weak var delegate: NormalUserDelegate?

func test() {

self.delegate?.showAddressView()

}

Protocol

protocol NormalUserDelegate: class {
    func showAddressView()
}

I couldn't make it work. Any idea?

like image 518
Utku Dalmaz Avatar asked Mar 05 '26 00:03

Utku Dalmaz


1 Answers

The way I see it, you have 2 decent options to use a delegate pattern. 1 terrible option that will work but it's hacky and lazy, and then you have the broadcast receiver pattern.

2 decent options

1 - Pass the delegate forward

class VC1: UIViewController, SomeDelegate {

    func delegateFunction() {}

    func showNextVC() {
        let next = VC2()
        next.forwardingDelegate = self
        present(next, animated: true)
    }
}

class VC2: UIViewController {
    var forwardingDelegate: SomeDelegate? = nil

    func showNextVC() {
        let next = VC3()
        next.delegate = forwardingDelegate
        present(next, animated: true)
    }
}

2 - Pass the 3rd controller to the second controller


class VC1: UIViewController, SomeDelegate {

    func delegateFunction() {}

    func showNextVC() {
        let final = VC3()
        final.delegate = self

        let next = VC2(withControllerToPresent: final)
        present(next, animated: true)
    }
}

class VC2: UIViewController {
    let controller: UIViewController

    init(withControllerToPresent controller: UIViewController) {
        self.controller = controller
        super.init(withNibName: nil, bundle: nil 
    }

    func showNextVC() {
        present(controller, animated: true)
    }
}

class VC3: UIViewController { 
    var delegate: SomeDelegate? = nil
}

1 Terrible Option

Use a singleton/global var.... (please dont)

Personal Opinion

I've done both of the first two options... They work. But the broadcast receiver pattern is probably better because it would be cleaner. VC2 shouldn't need to forward anything to 3. Just make sure to namespace your notification specific enough to not catch it by anything else later.

like image 84
Jake Avatar answered Mar 06 '26 13:03

Jake