如何从目标 VC 的子级为协议设置委托?

Posted

技术标签:

【中文标题】如何从目标 VC 的子级为协议设置委托?【英文标题】:How can I set the delegate for a protocol from the child of the destination VC? 【发布时间】:2019-10-31 16:46:47 【问题描述】:

MasterVC -> DetailVC -> ChildVC

我有一个SplitViewController,主端有一个表,细节端有第二个表。可以选择生成子 VC 的详细信息表单元格。目前,我在主服务器上定义了一个协议,让我知道何时选择了单元格。 (这样我可以根据需要更新详细信息方面。)我希望详细信息视图的子 vc 也接收该消息,但我不确定如何设置委托。我尝试的是在 ChildVC 中使用 prepare for segue 来获取对 MasterVC 的引用,如下所示:

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

但遗憾的是,这似乎不起作用。我至少在正确的轨道上吗?谢谢!

【问题讨论】:

如果子 VC 在创建单元格时存在,难道你不能在指向子 VC 的单元格中创建第二个委托变量,然后在选中时让单元格调用这两个委托方法吗? (显然也使 `child VC 符合协议) 如果您需要超过 1 个更改监听器,您应该使用通知 更具体地检查 swift 中的观察者模式。 我确实切换到了通知 - 实施起来稍微容易一些,而且效果很好!谢谢大家。 【参考方案1】:

如果你想在你的 DetailVC 中触摸单元格后传递一些数据,你可以使用 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")
    


【讨论】:

【参考方案2】:

class 是reference type,所以当你将delegate 定义为class 时,你不需要做其他事情,它应该可以工作

【讨论】:

以上是关于如何从目标 VC 的子级为协议设置委托?的主要内容,如果未能解决你的问题,请参考以下文章

仅在 Safari 中 - 位置:固定子级在父级为位置时被切断:固定且溢出:隐藏

从委托的源 ViewController 调用异步闭包

UIView - “用户交互启用”父级为假但子级为真?

iOS 自定义容器 VC 和需要特定方向的子级

Swift 协议委托返回 nil

升级到 Qt 5.15 后,ListView 委托中的父级为空