【问题标题】:Different behavior between addTarget and addGestureRecognizeraddTarget 和 addGestureRecognizer 之间的不同行为
【发布时间】:2019-02-26 09:21:01
【问题描述】:

我有一个函数可以创建一个以选择器函数为目标的按钮。按钮的地址被传递给handleSelectPhoto

lazy var image1Button = createButton(selector: #selector(handleSelectPhoto))
func createButton(selector: Selector) -> UIButton {
    let button = UIButton(type: .system)
    button.addTarget(self, action: selector, for: .touchUpInside)
    return button
}
@objc func handleSelectPhoto(button: UIButton) {
    // Do something with button, this works
}

现在,我正在尝试将上面的类从 UIButton 更改为 UIImageView,如下所示,

lazy var image1Button = createButton(selector: #selector(handleSelectPhoto))
func createButton(selector: Selector) -> UIImageView {
    let view = UIImageView()
    view.addGestureRecognizer(UITapGestureRecognizer(target: self, action: selector))
    view.isUserInteractionEnabled = true
    return view
}
@objc func handleSelectPhoto(button: UIImageView) {
    // HERE, button does not get passed
}

通过上述更改,handleSelectPhoto 中的按钮实例不正确。我无法将其读取为 UIImageView 类型。

如果我使用addGestureRecognizer 添加选择器函数,在选择器函数如何使用参数执行方面,它的行为是否与使用addTarget 添加选择器函数不同?也许我不明白这个选择器功能是如何工作的......

【问题讨论】:

    标签: swift uigesturerecognizer selector addtarget


    【解决方案1】:

    UIGestureRecognizerUIButton 之类的对象添加目标只会将一个参数传递给所选函数。此参数取决于您要添加目标的类型。

    在您的情况下,第一个代码 sn-p 有效,因为您将 target 添加到 UIButton,因此您选择的函数将传递给这个 UIButton 实例。

    在您的第二个场景中,您将 target 添加到 UITapGestureRecognizer,因此传递的实例将正是这个手势识别器,它不能UIImageView 类型.

    所以从目标参数的角度来看UIGestureRecognizerUIButton之间的区别是没有区别的。它们都将它们的实例传递给选定的函数。

    UIView 子类的角度来看,UIGestureRecognizer 不是UIView 的子类,而UIButton 是。这就是为什么您可以在第一个 sn-p 中使用传递的 UIButton 实例。在第二个 sn-p 中,您需要使用 UIGestureRecognizerview 属性

    guard let imageView = gestureRecognizer.view as? UIImageView else { return }
    

    除了您的实际问题之外,澄清如何正确编写#selectors 似乎很重要。 您已经做对了。 无需更改。有人可能会说您需要将(_:): 添加到您的选择器中,如下所示:#selector(handleSelectPhoto(_:)),但事实并非如此。一般情况下,只需要在选择具有不同参数数量但基名相同的重载方法的方法时添加这些特殊字符。

    【讨论】:

      【解决方案2】:

      在设置选择时,您应该通过在方法名称末尾添加: 来表明您的函数将接受参数。

      lazy var image1Button = createButton(selector: #selector(handleSelectPhoto:))
      

      UIKit 将自动理解选择器方法参数的类型为UITapGestureRecognizer。现在像这样重写下面的方法,你会很高兴的。

      @objc func handleSelectPhoto(gesture: UITapGestureRecognizer) {
              if let buttonImageView = gesture.view as? UIImageView {
                  //Here you can make changes in imageview what ever you want.
              }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2014-11-01
        • 1970-01-01
        • 2018-05-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多