Forwarding UIGesture to views behind

后端 未结 5 1353
长情又很酷
长情又很酷 2020-11-29 20:21

I am working on an iphone (iOS 4.0 or later) app and having some troubles with touch handling between multiple views. I am having a view structure like this

         


        
5条回答
  •  渐次进展
    2020-11-29 21:06

    I did something similar some time ago. I wanted to do two different things with one finger and two or more fingers. My solution might need some tweak for you and i can't ensure everything will work exactly the same in your code-environment. I did not find proper documentation of hitTest and why it is called multiple times in a row. So i did some testing and came to a solution, how to separate one and multi-finger gestures, which worked very well for my needs.

    I had this view hierarchy:

    ---> A superView 
     |
     ---> ScrollView - A - all touches
     |
     ---> ScrollView - B - only two+ finger scroll (exactly on top of A, completely blocking A).
    

    I implemented the switch in hitTest of the superView:

    BOOL endDrag; // indicates scrollviewB did finish
    BOOL shouldClearHitTest; // bool to help calling the method clearHitTest only once.
    BOOL multiTouch; // needed for the method clearHitTest to know if a multi-touch is detected or not
    NSMutableArray *events; // store all events within one eventloop/touch;
    
    
    - (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
        if (!endDrag) {
            if (!shouldClearHitTest) { // as hitTest will be called multible times in one event-loop and i need all events, i will clean the temporaries when everything is done
                shouldClearHitTest = YES;
                [[NSRunLoop mainRunLoop] performSelector:@selector(clearHitTest) target:self argument:nil order:1 modes:[NSArray arrayWithObject:NSRunLoopCommonModes]];
            }
            [events addObject:event]; // store the events so i can access them after all hittests for one touch are evaluated
    
            if (event.type == UIEventTypeTouches && ([_events count] > 3 || [[event allTouches] count] > 0 || _currentEvent)) { // two or more fingers detected. at least for my view hierarchy
                multiTouch = YES;
                return scrollViewB;
            }
        }else {
            endDrag = NO;
        }
        return scrollViewA;
    }
    
    - (void)clearHitTest {
        if (shouldClearHitTest) {
            shouldClearHitTest = NO;
            [events removeAllObjects];
            if (multiTouch) {
               // Do some special stuff for multiTouch
            }
            multiTouch = NO;
        }
    }
    

提交回复
热议问题