Ios 在Swift中将参数传递给选择器
我正在以编程方式将UITapGestureRecognitor添加到我的一个视图中:Ios 在Swift中将参数传递给选择器,ios,swift,uikit,selector,Ios,Swift,Uikit,Selector,我正在以编程方式将UITapGestureRecognitor添加到我的一个视图中: let gesture = UITapGestureRecognizer(target: self, action: #selector(self.handleTap(modelObj:myModelObj))) self.imageView.addGestureRecognizer(gesture) func handleTap(modelObj: Model) { // Doing stuff wi
let gesture = UITapGestureRecognizer(target: self, action: #selector(self.handleTap(modelObj:myModelObj)))
self.imageView.addGestureRecognizer(gesture)
func handleTap(modelObj: Model) {
// Doing stuff with model object here
}
我遇到的第一个问题是“#selector”的参数没有引用“@Objc”方法、属性或初始值设定项
酷,所以我在handleTap签名中添加了@objc:
@objc func handleTap(modelObj: Model) {
// Doing stuff with model object here
}
现在我得到了错误“方法不能标记为@objc,因为参数的类型不能在Objective-C中表示
这只是一个建筑物地图的图像,一些图钉图像表示感兴趣点的位置。当用户点击其中一个引脚时,我想知道他们点击了哪个兴趣点,我有一个模型对象来描述这些兴趣点。我使用这个模型对象来给出pin图像,它在地图上的坐标,因此我认为将该对象发送给手势处理程序会很容易。看起来您误解了一些事情 使用时,函数签名必须具有某种形式
func doSomething(sender: Any)
或
在哪里
sender
参数是发送操作消息的控制对象
在您的情况下,发送方是uitappesturerecognizer
另外,#selector()
应该包含func签名,而不包括传递的参数。所以对于
func handleTap(sender: UIGestureRecognizer) {
}
你应该
let gesture = UITapGestureRecognizer(target: self, action: #selector(handleTap(sender:)))
假设func和手势位于视图控制器内,其中
modelObj
是属性/ivar,则无需将其与手势识别器一起传递,您只需在handleTap
步骤1:创建发送方的自定义对象中引用即可
步骤2:添加要更改的属性,其中包含发送方的自定义对象
btnFullRemote.name = "Nik"
btnFullRemote.customObject = customObject
btnFullRemote.customObject2 = customObject2
btnFullRemote.addTarget(self, action: #selector(self.btnFullRemote(_:)), for: .touchUpInside)
步骤3:在接收函数中将发送方类型转换为自定义对象,并访问这些属性
@objc public func btnFullRemote(_ sender: Any) {
var name : String = (sender as! CustomButton).name as? String
var customObject : customObject = (sender as! CustomButton).customObject as? customObject
var customObject2 : customObject2 = (sender as! CustomButton).customObject2 as? customObject2
}
例如:
如果要发送字符串或任何自定义对象,请单击按钮,然后
步骤1:创建
class CustomButton : UIButton {
var name : String = ""
var customObject : Any? = nil
var customObject2 : Any? = nil
convenience init(name: String, object: Any) {
self.init()
self.name = name
self.customObject = object
}
}
步骤2-a:在情节提要中设置自定义类
步骤2-b:使用自定义类创建该按钮的IBOutlet,如下所示
@IBOutlet weak var btnFullRemote: CustomButton!
步骤3:添加要更改的属性,其中包含发送方的自定义对象
btnFullRemote.name = "Nik"
btnFullRemote.customObject = customObject
btnFullRemote.customObject2 = customObject2
btnFullRemote.addTarget(self, action: #selector(self.btnFullRemote(_:)), for: .touchUpInside)
步骤4:在接收函数中将发送方类型转换为自定义对象,并访问这些属性
@objc public func btnFullRemote(_ sender: Any) {
var name : String = (sender as! CustomButton).name as? String
var customObject : customObject = (sender as! CustomButton).customObject as? customObject
var customObject2 : customObject2 = (sender as! CustomButton).customObject2 as? customObject2
}
这可能是一个糟糕的做法,但我只是简单地添加了我想要恢复的内容
button.restorationIdentifier=urlString
及
Swift 5.0 iOS 13
我同意他的回答。这是我的2美分,相同但不同的技术;最低版本
创建一个自定义类,抛出一个枚举以保持/使代码尽可能可维护
enum Vs: String {
case pulse = "pulse"
case precision = "precision"
}
class customTap: UITapGestureRecognizer {
var cutomTag: String?
}
使用它,确保将自定义变量设置到bargin中。在这里使用一个简单的标签,注意最后一行,重要的标签通常不是交互式的
let precisionTap = customTap(target: self, action: #selector(VC.actionB(sender:)))
precisionTap.customTag = Vs.precision.rawValue
precisionLabel.addGestureRecognizer(precisionTap)
precisionLabel.isUserInteractionEnabled = true
注意,我想使用纯枚举,但是Objective C不支持它,所以我们使用一个基本类型,在本例中是String
@objc func actionB(sender: Any) {
// important to cast your sender to your cuatom class so you can extract your special setting.
let tag = customTag as? customTap
switch tag?.sender {
case Vs.pulse.rawValue:
// code
case Vs.precision.rawValue:
// code
default:
break
}
}
就在这里。只需创建一个自定义的UITapgestureRecognitizer类=>
import UIKit
class OtherUserProfileTapGestureRecognizer: UITapGestureRecognizer {
let userModel: OtherUserModel
init(target: AnyObject, action: Selector, userModel: OtherUserModel) {
self.userModel = userModel
super.init(target: target, action: action)
}
}
然后创建UIImageView扩展=>
import UIKit
extension UIImageView {
func gotoOtherUserProfile(otherUserModel: OtherUserModel) {
isUserInteractionEnabled = true
let gestureRecognizer = OtherUserProfileTapGestureRecognizer(target: self, action: #selector(self.didTapOtherUserImage(_:)), otherUserModel: otherUserModel)
addGestureRecognizer(gestureRecognizer)
}
@objc internal func didTapOtherUserImage(_ recognizer: OtherUserProfileTapGestureRecognizer) {
Router.shared.gotoOtherUserProfile(otherUserModel: recognizer.otherUserModel)
}
}
现在像=>
self.userImageView.gotoOtherUserProfile(otherUserModel: OtherUserModel)
不能像那样将值传递给选择器。为什么不能将该值保存在实例变量中并从选择器方法访问它?可能是的重复。中的部分也很好地展示了操作方法可以采取的三种形式。为了补充这个伟大的答案,某些对象类型(如Timer)具有
userInfo:Any?
参数,可以与此解决方案结合使用,以便将模型对象传递给发送方。聪明的答案提供了一个很好的解决方案(而不是说这是不可能的,就像我找到的大多数答案所说的那样)…尝试了这种方法,并且可以确认它可以工作自定义对象包装器来传递您所需要的一切!太聪明了。谢谢。糟糕的实践…是的。太可怕了!工藤的!太棒了。这很有效。但我认为应该纠正@objc func actionB(发送方:任意){let tap=发送方为?customTap开关tap?.customTag{…这个问题在一段时间前得到了回答,并且已经有了一个公认的答案。这意味着任何额外的答案都应该为这个问题的任何读者提供一个新的视角。因此,我建议您为您的答案添加更多的上下文,并描述为什么它提供了一种解决问题的独特方法。有关更多信息,请参阅关于回答问题,请看这里:
cell.btn.tag = indexPath.row //setting tag
cell.btn.addTarget(self, action: #selector(showAlert(_ :)), for: .touchUpInside)
@objc func showAlert(_ sender: UIButton){
print("sender.tag is : \(sender.tag)")// getting tag's value
}