Search code examples
iosswiftdelegatesprotocolsuisplitviewcontroller

How can I set the delegate for a protocol from the child of the destination VC?


MasterVC -> DetailVC -> ChildVC

I have a SplitViewController with a table on the master side and a second table on the detail side. The detail table cells can be selected which brings up a child VC. Currently, I have a protocol defined on the master that lets me know when a cell has been selected. (That way I can update the detail side as needed.) I would like the child vc of the detail view to receive that message as well, but I'm not sure how to set the delegate. What I've tried is to use prepare for segue in the ChildVC to get a reference to the MasterVC like this:

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    if let nav = segue.destination as? UINavigationController {
        if let masterVC = nav.topViewController as? MasterVC {
            masterVC = self
        }
    }
}

But sadly, that doesn't seem to work. Am I on the right track, at least? Thank you!


Solution

  • If you want pass some data after you touch cell in your DetailVC, you could use NotificationCenter

    class MasterVC: UIViewController {
    
        override func viewDidLoad() {
            super.viewDidLoad()
            NotificationCenter.default.addObserver(self,
                                                   selector: #selector(childVCDidSelect(_:)),
                                                   name: DetailVC.selectionNotificationName,
                                                   object: nil)
        }
    
        @objc func childVCDidSelect(_ value: String) {
            print("MasterVC recieve \(value) from DetailVC")
        }
    }
    
    class DetailVC: UIViewController, UITableViewDelegate {
    
        static var selectionNotificationName: NSNotification.Name {
            return NSNotification.Name(rawValue: "DetailVCSelectionNotification")
        }
    
        func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
            // value variabl could by any type, maybe you want pass model for selected index path.
            let value = "your value"
            // When you call NotificationCenter post, you past value to all subscribers,
            // who has subcribed NotificationCenter.default.addObserver for DetailVC.selectionNotificationName
            NotificationCenter.default.post(name: DetailVC.selectionNotificationName, object: value)
        }
    }
    
    class ChildVC: UIViewController {
    
        override func viewDidLoad() {
            super.viewDidLoad()
            NotificationCenter.default.addObserver(self,
                                                   selector: #selector(childVCDidSelect(_:)),
                                                   name: DetailVC.selectionNotificationName,
                                                   object: nil)
        }
    
        @objc func childVCDidSelect(_ value: String) {
            print("ChildVC recieve \(value) from DetailVC")
        }
    }