Alien
Alien

Reputation: 3668

swift4 selector function without parameters

In my new project, when i tap a button, it will pop up a menu view from bottom.

enter image description here

and the code:

blackView.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(handleDismiss)))

and the handleDismiss function:

@objc func handleDismiss(callback:(() -> ())?) {

        UIView.animate(withDuration: 0.3, animations: {
            self.blackView.alpha = 0
            //......
            }
        }) { (completed: Bool) in
            callback?()
        }
    }

then i tap the menu view's Cancel cell, call the handleDismiss function with a callback parameter . it's working.

if item.icon == "close" {
    handleDismiss(callback: {
        print("callback now")
    })
  }

but if i tap the black mask view(trigger action: #selector(handleDismiss))), it's error like below:

enter image description here

does anyone has idea?

Upvotes: 4

Views: 1396

Answers (2)

ryantxr
ryantxr

Reputation: 4219

The function to handle a gesture must be defined as shown below.

@IBAction func myActionMethod(_ sender: UIGestureRecognizer)

When the UITapGestureRecognizer calls the action function in your controller, it passes the UIGestureRecognizer object as the parameter. You can't define the action function to take any parameter you want.

Upvotes: 1

dr_barto
dr_barto

Reputation: 6075

When wiring up an action via a selector you have to match the expected method signature. Your handler method handleDismiss has a closure parameter which is not compatible with what UITapGestureRecognizer expects; in this case that's a single gesture recognizer parameter, or no parameter. So you have to add a second method which acts as the tap event listener and forwards the call to the dismiss handler:

@objc func didTapDismiss() {
  handleDismiss(callback: nil) // call your dismiss logic from the tap handler
}

Your dismiss handler code can stay as it is (you can get rid of @objc which is no longer needed though):

func handleDismiss(callback:(() -> ())?) {
  ...

When hooking up the tap listener, use the new tap handler action:

blackView.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(didTapDismiss)))

A final note: I don't know your exact use case but you might make things overly complicated by using tap gesture recognizers; have you considered to just use UIButton instead?

Upvotes: 5

Related Questions