Why does UINavigationBar steal touch events?

后端 未结 12 2609
耶瑟儿~
耶瑟儿~ 2020-11-27 18:48

I have a custom UIButton with UILabel added as subview. Button perform given selector only when I touch it about 15points lower of top bound. And when I tap above that area

12条回答
  •  暗喜
    暗喜 (楼主)
    2020-11-27 19:21

    The solution for me was the following one:

    First: Add in your application (It doesn't matter where you enter this code) an extension for UINavigationBar like so: The following code just dispatch a notification with the point and event when the navigationBar is being tapped.

    extension UINavigationBar {
    open override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
        NotificationCenter.default.post(name: NSNotification.Name(rawValue: "tapNavigationBar"), object: nil, userInfo: ["point": point, "event": event as Any])
        return super.hitTest(point, with: event)
        }
    }
    

    Then in your specific view controller you must listen to this notification by adding this line in your viewDidLoad:

    NotificationCenter.default.addObserver(self, selector: #selector(tapNavigationBar), name: NSNotification.Name(rawValue: "tapNavigationBar"), object: nil)
    

    Then you need to create the method tapNavigationBar in your view controller as so:

    func tapNavigationBar(notification: Notification) {
        let pointOpt = notification.userInfo?["point"] as? CGPoint
        let eventOpt = notification.userInfo?["event"] as? UIEvent?
        guard let point = pointOpt, let event = eventOpt else { return }
    
        let convertedPoint = YOUR_VIEW_BEHIND_THE_NAVBAR.convert(point, from: self.navigationController?.navigationBar)
        if YOUR_VIEW_BEHIND_THE_NAVBAR.point(inside: convertedPoint, with: event) {
            //Dispatch whatever you wanted at the first place.
        }
    }
    

    PD: Don't forget to remove the observation in the deinit like so:

    deinit {
        NotificationCenter.default.removeObserver(self)
    }
    

    That's it... That's a little bit 'tricky', but it's a good workaround for not subclassing and getting a notification anytime the navigationBar is being tapped.

提交回复
热议问题