UIGestureRecognizer blocks subview for handling touch events

后端 未结 10 1016
北恋
北恋 2020-11-28 19:32

I\'m trying to figure out how this is done the right way. I\'ve tried to depict the situation: \"enter

相关标签:
10条回答
  • 2020-11-28 19:47

    implement a delegate for all the recognizers of the parentView and put the gestureRecognizer method in the delegate that is responsible for simultaneous triggering of recognizers:

    func gestureRecognizer(UIGestureRecognizer,       shouldBeRequiredToFailByGestureRecognizer:UIGestureRecognizer) -> Bool {
    if (otherGestureRecognizer.view.isDescendantOfView(gestureRecognizer.view)) {
        return true
        } else {
        return false
    }
    

    }

    U can use the fail methods if u want to make the children be triggered but not the parent recognizers:

    https://developer.apple.com/reference/uikit/uigesturerecognizerdelegate

    0 讨论(0)
  • 2020-11-28 19:49

    Building on @Pin Shih Wang answer. We ignore all taps other than those on the view containing the tap gesture recognizer. All taps are forwarded to the view hierarchy as normal as we've set tapGestureRecognizer.cancelsTouchesInView = false. Here is the code in Swift3/4:

    func ensureBackgroundTapDismissesKeyboard() {
        let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(handleTap))
        tapGestureRecognizer.cancelsTouchesInView = false
        self.view.addGestureRecognizer(tapGestureRecognizer)
    }
    
    @objc func handleTap(recognizer: UIGestureRecognizer) {
        let location = recognizer.location(in: self.view)
        let hitTestView = self.view.hitTest(location, with: UIEvent())
        if hitTestView?.gestureRecognizers?.contains(recognizer) == .some(true) {
            // I dismiss the keyboard on a tap on the scroll view
            // REPLACE with own logic
            self.view.endEditing(true)
        }
    }
    
    0 讨论(0)
  • 2020-11-28 19:59

    One possibility is to subclass your gesture recognizer (if you haven't already) and override -touchesBegan:withEvent: such that it determines whether each touch began in an excluded subview and calls -ignoreTouch:forEvent: for that touch if it did.

    Obviously, you'll also need to add a property to keep track of the excluded subview, or perhaps better, an array of excluded subviews.

    0 讨论(0)
  • 2020-11-28 20:04

    I had a very similar problem and found my solution in this SO question. In summary, set yourself as the delegate for your UIGestureRecognizer and then check the targeted view before allowing your recognizer to process the touch. The relevant delegate method is:

    - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer
           shouldReceiveTouch:(UITouch *)touch
    
    0 讨论(0)
  • 2020-11-28 20:04

    I created a UIGestureRecognizer subclass designed for blocking all gesture recognizers attached to a superviews of a specific view.

    It's part of my WEPopover project. You can find it here.

    0 讨论(0)
  • 2020-11-28 20:05

    It is possible to do without inherit any class.

    you can check gestureRecognizers in gesture's callback selector

    if view.gestureRecognizers not contains your gestureRecognizer,just ignore it

    for example

    - (void)viewDidLoad
    {
        UITapGestureRecognizer *singleTapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self     action:@selector(handleSingleTap:)];
        singleTapGesture.numberOfTapsRequired = 1;
    }
    

    check view.gestureRecognizers here

    - (void)handleSingleTap:(UIGestureRecognizer *)gestureRecognizer
    {
        UIEvent *event = [[UIEvent alloc] init];
        CGPoint location = [gestureRecognizer locationInView:self.view];
    
        //check actually view you hit via hitTest
        UIView *view = [self.view hitTest:location withEvent:event];
    
        if ([view.gestureRecognizers containsObject:gestureRecognizer]) {
            //your UIView
            //do something
        }
        else {
            //your UITableView or some thing else...
            //ignore
        }
    }
    
    0 讨论(0)
提交回复
热议问题