我有一个主视图,我添加了一个子视图。我想从子视图中触发一个事件并在主视图中捕获事件。所以我使用了协议实现,但是我没有收到来自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")
}
}
答案 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。
解决方案非常自我解释。