addTarget和addGestureRecognizer之间的行为不同

时间:2019-02-26 09:21:01

标签: swift uigesturerecognizer selector addtarget

我有一个函数,该函数创建一个以选择器函数为目标的按钮。按钮的地址将传递到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添加选择器功能不同吗?也许我不了解此选择器功能的工作原理...

2 个答案:

答案 0 :(得分:2)

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

在您的情况下,第一个代码段有效,因为您要向UIButton添加 target ,因此您选择的函数将通过此UIButton实例传递。

在第二种情况下,将 target 添加到UITapGestureRecognizer,因此传递的实例将正是此手势识别器,不能是{ {1}}。

因此,从{em> target参数角度来看,UIImageViewUIGestureRecognizer之间没有区别。它们都将实例传递给选定的函数。

UIButton子类的角度来看,区别在于UIView不是UIGestureRecognizer的子类,而UIView是。这就是为什么您只能在第一个代码段中使用传递的UIButton实例。在第二个代码段中,您需要使用UIButton view属性

UIGestureRecognizer

除了您的实际问题之外,弄清如何正确编写guard let imageView = gestureRecognizer.view as? UIImageView else { return } 似乎很重要。 您已经将其纠正了。无需更改。有人可能说您需要像这样将#selector(_:)添加到选择器::,但这不是事实。通常,仅在选择具有重载方法且参数数量不同但基本名称相同的方法时,才需要添加这些特殊字符。

答案 1 :(得分:1)

在设置选择时,应在方法名称的末尾添加:来告诉您函数将接受参数。

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.
        }
}