Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Passing arguments to selector in Swift

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.

like image 952
mike Avatar asked Apr 06 '17 09:04

mike


People also ask

How do you pass parameters in OBJC func?

The action method must take one parameter, namely the sender (which in this case will be the button). If the action method needs more information at the time that it is called, you must provide that information in some other way, e.g. as an instance property that the action method can access when it is called.

How do you call a selector in Swift?

The solution to your problem is to pass the object that should run the selector method along with the selector to the initialisation of the ValueAnimator object. Also update the timerCallback() : @objc func timerCallback() { ... _ = target.

What does @objc mean in Swift?

That's where the @objc attribute comes in: when you apply it to a class or method it instructs Swift to make those things available to Objective-C as well as Swift code.


2 Answers

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() 

or

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

like image 59
Ashley Mills Avatar answered Sep 28 '22 02:09

Ashley Mills


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

enter image description here

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  } 
like image 21
Ninad Kambli Avatar answered Sep 28 '22 04:09

Ninad Kambli