UIView 到 UIViewController 通过协议的通信不起作用

UIView to UIViewController communication via protocol not working

也许我在这里遗漏了一些真正基本的东西,但在盯着代码看了一个小时左右之后,我的大脑正在经历低谷循环,我希望能重新审视这个问题。

我有以下 UIView:

import UIKit

protocol DetailViewWillShowUpDelegate {
    func sendDetailOpened(_ openedBool: Bool)
}

class locationXIBController: UIView {

    @IBOutlet weak var loationLabel: UILabel!
    @IBOutlet weak var vsedniOteviraciDobaLabel: UILabel!
    @IBOutlet weak var prijmajiKartyLabel: UILabel!
    @IBOutlet weak var detailViewButtonOutlet: UIButton!
    @IBOutlet weak var backgroundViewButton: UIButton!

    let openedBool = true
    var detailViewWillShowUpDelegate: DetailViewWillShowUpDelegate?

    override func awakeFromNib() {
        super.awakeFromNib()
    }

    @IBAction func vecerkaDetailButtonPressed(_ sender: UIButton) {
        detailViewWillShowUpDelegate?.sendDetailOpened(openedBool)
        print("pressed")
    }

    override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
        if let result = detailViewButtonOutlet.hitTest(convert(point, to: detailViewButtonOutlet), with: event) {
            return result
        }
        return backgroundViewButton.hitTest(convert(point, to: backgroundViewButton), with: event)
    }

}

现在的问题是,当我 call/press vecerkaDetailButtonPressed 函数时,我在控制台中得到 "pressed" 输出,但由于某种原因协议没有通过。

另一面看起来像这样(为简单起见已剥离):

class MapViewController: UIViewController, MKMapViewDelegate, CLLocationManagerDelegate {

    let locationXIB = locationXIBController()
    let isVecerkaDetailOpened = false

    override func viewDidLoad() {
       locationXIB.detailViewWillShowUpDelegate = self
    }



extension MapViewController: DetailViewWillShowUpDelegate {
    func sendDetailOpened(_ openedBool: Bool) {
        isVecerkaDetailOpened = openedBool
        print("success")
    }
}

我知道执行时的协议值为零。正如我所说,任何帮助都将不胜感激,谢谢!

首先,几个命名约定问题:

名称 locationXIBController 对于 UIView 对象来说是一个错误的选择。它是一个视图对象,而不是控制器对象。

其次,class Swift 中的名称应以大写字母开头。所以 LocationXIBView 将是该视图更好的名称 class.

接下来,你的代码

let locationXIB = locationXIBController()

...错了。这会创建一个全新的 locationXIBController class 实例,您永远不会将其安装在视图层次结构中。您应该将该行设为 IBOutlet:

@IBOutlet weak var locationXIB: locationXIBController!

然后你应该从 StoryBoard 中的 locationXIBController 控件拖动到视图控制器中的插座上。这将导致 Interface Builder 连接插座。

现在,当您 运行 您的程序时,变量 locationXIB 将在加载时从您的 storyboard/XIB 连接到 locationXIBController 视图。

除了@Duncan C 的回答,您可能会检查 MapViewController class 中 viewDidLoad() 方法顶部是否需要 super.viewDidLoad()?不这样做可能会导致您的应用出现古怪的事情。

我问:

So does detailViewWillShowUpDelegate actually point at anything, or is it nil?

你回复了:

I just tried debugging and it is actually nil

这就是问题所在...您需要设置 detailViewWillShowUpDelegate 以指向有效的委托对象。这通常在 .xib 文件或情节提要中完成,有时人们会忘记建立这种联系,因此请检查它是否有意义。否则,您只需要在相关代码可以 运行 并设置它之前的某个时刻获得对委托的引用。

@Paulw11 的回答

我终于通过这样的交流设法让它工作了:

步骤 1) 1:1 通过 MKAnnotation 和 MKAnnotationView 之间的协议通信

步骤 2) 1:1 通过 MKAnnotationView 和 MapViewController 之间的协议通信传递相同的数据

终于成功了,谢谢!