Passing arguments to selector in Swift

怎甘沉沦 提交于 2019-11-26 09:30:02

问题


I\'m programmatically adding a UITapGestureRecognizer to one of my views:

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
}

The first problem I encountered was \"Argument of \'#selector\' does not refer to an \'@Objc\' method, property, or initializer.

Cool, so I added @objc to the handleTap signature:

@objc func handleTap(modelObj: Model) {
  // Doing stuff with model object here
}

Now I\'m getting the error \"Method cannot be marked @objc because the type of the parameter cannot be represented in Objective-C.

It\'s just an image of the map of a building, with some pin images indicating the location of points of interest. When the user taps one of these pins I\'d like to know which point of interest they tapped, and I have a model object which describes these points of interest. I use this model object to give the pin image it\'s coordinates on the map so I thought it would have been easy for me to just send the object to the gesture handler.


回答1:


It looks like you're misunderstanding a couple of things.

When using target/action, the function signature has to have a certain form…

func doSomething(sender: Any)

or

func doSomething(sender: Any, forEvent event: UIEvent)

where…

The sender parameter is the control object sending the action message.

In your case, the sender is the UITapGestureRecognizer

Also, #selector() should contain the func signature, and does NOT include passed parameters. So for…

func handleTap(sender: UIGestureRecognizer) {

}

you should have…

let gesture = UITapGestureRecognizer(target: self, action: #selector(handleTap(sender:)))

Assuming the func and the gesture are within a view controller, of which modelObj is a property / ivar, there's no need to pass it with the gesture recogniser, you can just refer to it in handleTap




回答2:


Step 1: create the custom object of the sender.

step 2: add properties you want to change in that a custom object of the sender

step 3: typecast the sender in receiving function to a custom object and access those properties

For eg: on click of the button if you want to send the string or any custom object then

step 1: create

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

step 2-a: set the custom class in the storyboard as well

step 2-b: Create IBOutlet of that button with a custom class as follows

@IBOutlet weak var btnFullRemote: CustomButton!

step 3: add properties you want to change in that a custom object of the sender

btnFullRemote.name = "Nik"
btnFullRemote.customObject = customObject
btnFullRemote.customObject2 = customObject2
btnFullRemote.addTarget(self, action: #selector(self.btnFullRemote(_:)), for: .touchUpInside)

step 4: typecast the sender in receiving function to a custom object and access those properties

@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

}


来源:https://stackoverflow.com/questions/43251708/passing-arguments-to-selector-in-swift

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!