子视图之间的协议实现

时间:2018-02-16 10:55:29

标签: swift delegates protocols

我有一个主视图,我添加了一个子视图。我想从子视图中触发一个事件并在主视图中捕获事件。所以我使用了协议实现,但是我没有收到来自HomeViewController的消息。为什么?

协议

protocol MyDetectionDelegate : class {
    func somethingDiscovered(_ message : String )
}

主视图

class HomeViewController : UIViewController, MyDetectionDelegate {


 var childView : DetectionView!

 override func viewDidLoad() {
        super.viewDidLoad()

        childView = DetectionView(frame: CGRect.zero)
        childView.delegate = self
        self.view.addSubview(childView)
        childView.autoPinEdgesToSuperviewEdges(with: UIEdgeInsets.zero)

    }

 func somethingDiscovered(_ message: String) {
         print("Hi I discovered something : \(message)")
 }

}

子视图:

class DetectionView: UIView {

   // Delegation
   weak var delegate : MyDetectionDelegate?

   // Functions
   override init(frame: CGRect) {
        super.init(frame: frame)

        ....

        iDiscoveredSomething()
   }

   func iDiscoveredSomething(){

        delegate?.somethingDiscovered("5 potatoes")

   }

}

3 个答案:

答案 0 :(得分:1)

您没有看到委托触发任何函数,因为在设置委托之前首先运行初始化(在HomeViewController中)。因此,当您要调用delegate?

时,somethingDiscovered()引用实际上为零

您的设置正确,协议模式也可以。只是不是以这种特殊的方式。

答案 1 :(得分:1)

您的问题就在这里,

override init(frame: CGRect) {
    super.init(frame: frame)

    ....

    iDiscoveredSomething()
}

您正在View的init中调用方法。所以这个方法将通过委托引用来调用你的协议方法。但是没有找到代表参考,也没有发生任何事情。因此,我的建议是在您查看中添加按钮,并尝试在按钮的操作上调用委托。

答案 2 :(得分:0)

像这样发起你的UIView:

class  DetectionView: UIView {

var delegate: MyDetectionDelegate!

override init(frame: CGRect) {
    super.init(frame: frame)
}

convenience init(mainController: MyDetectionDelegate){
self.init()
delegate = mainController
// Write all the initiation codes here.

delegate.somethingDiscovered("Hello")
}

required init?(coder aDecoder: NSCoder) {
    fatalError("init(coder:) has not been implemented")
}
}

在Controller类中,启动如下视图:

 var detectionView = DetectionView.init(mainController: self)

向其添加一个框架,或者根据需要通过代码执行AutoLayout。

解决方案非常自我解释。