Charles Xavier
Charles Xavier

Reputation: 41

UITap Gesture Not being recognized

I have a view controller with a button that has the following action.

@IBAction func sourceButton(_ sender: Any) {
    let menu = sourceMenu()
    menu.openMenu()
}

The source menus class is an NSObject class with the following code.

class sourceMenu: NSObject {
    let blackView = UIView()

    public func openMenu(){

        if let window = UIApplication.shared.windows.filter({ $0.isKeyWindow }).first {
            blackView.frame = window.frame
            blackView.backgroundColor = UIColor(white: 0, alpha: 0.5)
            blackView.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(self.dismissMenu)))
            window.addSubview(blackView)
            UIView.animate(withDuration: 0.5) {
                self.blackView.alpha = 1
            }
        }


    }

    @objc public func dismissMenu(){
        UIView.animate(withDuration: 0.5) {
            self.blackView.alpha = 0

        }
    }

}

the function dismissMenu is not being called when I tap on the view controller. any ideas? Thank you.

Upvotes: 0

Views: 90

Answers (2)

Pancho
Pancho

Reputation: 4143

The problem is really that your object is being released from memory since it only lives within your function block. Once the function finishes its execution your memory gets cleared. You need to create an instance in your presenting UIViewController so the arc keeps it alive since the view controller will have a reference to it. You should declare a property like so.

class ViewController: UIViewController {

  let menu = sourceMenu()

  override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view.
  }

  @IBAction func tapAction(_ sender: Any) {
    menu.openMenu()
  }

}

Also you could just grab a reference to the keyWindow by simply doing UIApplication.shared.keyWindow

Also what's your reason for presenting this on the window instead of using your view controller? If this is something that every controller should be able to present why not making an extension instead? I would avoid presenting views from the window as it could lead to hidden issues.

Upvotes: 3

Ayazmon
Ayazmon

Reputation: 1380

I've encountered this issue once. The solution I found for myself was having a strong reference to the UITapGestureRecognizer. So what you should do is:

// Define a gesture variable in class
class sourceMenu: NSObject {
    var gestureRecognizer: UITapGestureRecognizer
}

// Use the variable in `openMenu` function
gestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(self.dismissMenu)) 
blackView.addGestureRecognizer(gestureRecognizer)

}

Hope this helps.

Upvotes: 0

Related Questions