swift - addTarget 和 addGestureRecognizer 之间的不同行为

标签 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 添加一个选择器函数不同,就如何使用参数执行选择器函数而言?也许我不明白这个选择器函数是如何工作的……

最佳答案

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

在您的例子中,第一个代码片段有效,因为您正在向 UIButton 添加一个目标,因此您选择的函数将传递给这个 UIButton 实例。

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

所以从目标参数的角度来看,UIGestureRecognizerUIButton 没有区别。他们都将自己的实例传递给选定的函数。

UIView 子类的角度来看,UIGestureRecognizer 不是 UIView 的子类,而是 UIButton 是。这就是为什么您可以在第一个代码段中使用传递的 UIButton 实例的原因。在第二个片段中,您需要使用 UIGestureRecognizer View 属性

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

除了您的实际问题之外,阐明如何正确编写 #selector 似乎很重要。 您已经做对了。无需更改。有些人可能会说您需要像这样将 (_:): 添加到您的选择器中:#selector(handleSelectPhoto(_:)) 但是这不是真的。通常,只有在选择具有不同数量参数但相同基名称的重载方法的方法时才需要添加这些特殊字符。

关于swift - addTarget 和 addGestureRecognizer 之间的不同行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54882088/

相关文章:

json - OpenWeatherMap 和 Swift 4

iOS 阻止向下滑动

iphone - 试图在 UIPanGestureRecognizer 上移动 UIImageView

objective-c - 定义为返回 id 的 SEL 如何表示返回 double 的方法?

ios - 在另一个自定义 ViewController 中更改自定义 UIView 的变量

ios - 在 View Controller 之间传输变量而不会出错

ios - 根据内容自动更改单元格高度 - Swift

ios - 带有 SWRevealViewController 的 Exc_bad_instruction

从未选择用于多个 OP 代码的 Java SocketChannel register()

swift - 如何使用 Swift 3 检测 macOS 默认模式和暗模式之间的切换