Search code examples
iosswiftuikitselector

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.


Solution

  • 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