addTarget 和 addGestureRecognizer 之间的不同行为
Different behavior between addTarget and addGestureRecognizer
我有一个函数可以创建一个带有选择器函数的按钮作为目标。按钮的地址被传递给 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
}
现在,我正在尝试将上面的 class 从 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
添加一个选择器函数不同,就如何使用参数执行选择器函数而言?也许我不明白这个选择器函数是如何工作的……
向 UIGestureRecognizer
或 UIButton
之类的对象添加目标只会将一个参数传递给所选函数。此参数取决于您要添加目标的类型。
在您的情况下,第一个代码片段有效,因为您将 target 添加到 UIButton
,因此您选择的函数将传递给此 UIButton 实例。
在第二种情况下,您将 目标 添加到 UITapGestureRecognizer
,因此传递的实例将正是这个手势识别器,不能 属于 UIImageView
.
类型
所以从目标参数的角度来看,UIGestureRecognizer
和UIButton
没有区别。他们都将自己的实例传递给选定的函数。
从 UIView
子类的角度来看,区别在于 UIGestureRecognizer
不是 UIView
的子类,但 UIButton
是。这就是为什么您可以在第一个代码段中使用传递的 UIButton
实例的原因。在第二个片段中,您需要使用 视图 属性 of UIGestureRecognizer
.
guard let imageView = gestureRecognizer.view as? UIImageView else { return }
除了您的实际问题之外,阐明如何正确编写 #selector
似乎很重要。 您已经做对了。无需更改。有些人可能会说您需要像这样将 (_:)
或 :
添加到您的选择器中:#selector(handleSelectPhoto(_:))
但事实并非如此。一般情况下,只有在选择重载方法的参数数量不同但基名相同的方法时,才需要添加这些特殊字符。
您应该在设置选择时告诉您,您的函数将通过在方法名称末尾添加 :
来接受参数。
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.
}
}
我有一个函数可以创建一个带有选择器函数的按钮作为目标。按钮的地址被传递给 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
}
现在,我正在尝试将上面的 class 从 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
添加一个选择器函数不同,就如何使用参数执行选择器函数而言?也许我不明白这个选择器函数是如何工作的……
向 UIGestureRecognizer
或 UIButton
之类的对象添加目标只会将一个参数传递给所选函数。此参数取决于您要添加目标的类型。
在您的情况下,第一个代码片段有效,因为您将 target 添加到 UIButton
,因此您选择的函数将传递给此 UIButton 实例。
在第二种情况下,您将 目标 添加到 UITapGestureRecognizer
,因此传递的实例将正是这个手势识别器,不能 属于 UIImageView
.
所以从目标参数的角度来看,UIGestureRecognizer
和UIButton
没有区别。他们都将自己的实例传递给选定的函数。
从 UIView
子类的角度来看,区别在于 UIGestureRecognizer
不是 UIView
的子类,但 UIButton
是。这就是为什么您可以在第一个代码段中使用传递的 UIButton
实例的原因。在第二个片段中,您需要使用 视图 属性 of UIGestureRecognizer
.
guard let imageView = gestureRecognizer.view as? UIImageView else { return }
除了您的实际问题之外,阐明如何正确编写 #selector
似乎很重要。 您已经做对了。无需更改。有些人可能会说您需要像这样将 (_:)
或 :
添加到您的选择器中:#selector(handleSelectPhoto(_:))
但事实并非如此。一般情况下,只有在选择重载方法的参数数量不同但基名相同的方法时,才需要添加这些特殊字符。
您应该在设置选择时告诉您,您的函数将通过在方法名称末尾添加 :
来接受参数。
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.
}
}