Skip to content

Commit

Permalink
[platform_views] Fix duplicated touch event pass down to flutter view…
Browse files Browse the repository at this point in the history
… from platform view. (#8026)

Fix for flutter/flutter#27700 and flutter/flutter#24207

There are 2 fixes included in this PR.

The intercepting views sometime pass up the touches events to flutter view, even after the forward gesture recognizer pass the event to the flutter view. We only want the event to be passed to the flutter view once. So we let the intercepting view 'consumes' the event in this PR to fix the problem.

When a touch sequence has multiple touch points participated(e.g. Pinch gesture), the touchesBegan and touchesEnded can be triggered multiple times if the touches do not happen simultaneously. One example would be: when performing a pinch gesture with 2 fingers, I put down one finger, keep the finger on the screen, then put down another finger, perform pinch, lift up both finger at the same time. In this sequence, touchesBegan is called twice with each touch in one of the calls and touchesEnded is called once and has 2 touches in the callback. To handle this issue, we added a count to count the touches in one touch sequence. We only set the state to fail when the count reaches 0(That is all the touches has began in the current sequence is ended).
  • Loading branch information
Chris Yang committed Mar 4, 2019
1 parent 3d53e20 commit 36ca574
Showing 1 changed file with 29 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -353,6 +353,21 @@ - (void)blockGesture {
_delayingRecognizer.get().state = UIGestureRecognizerStateEnded;
}

// We want the intercepting view to consume the touches and not pass the touches up to the parent
// view. Make the touch event method not call super will not pass the touches up to the parent view.
// Hence we overide the touch event methods and do nothing.
- (void)touchesBegan:(NSSet<UITouch*>*)touches withEvent:(UIEvent*)event {
}

- (void)touchesMoved:(NSSet<UITouch*>*)touches withEvent:(UIEvent*)event {
}

- (void)touchesCancelled:(NSSet<UITouch*>*)touches withEvent:(UIEvent*)event {
}

- (void)touchesEnded:(NSSet*)touches withEvent:(UIEvent*)event {
}

@end

@implementation DelayingGestureRecognizer {
Expand Down Expand Up @@ -395,19 +410,24 @@ @implementation ForwardingGestureRecognizer {
// So this is safe as when FlutterView is deallocated the reference to ForwardingGestureRecognizer
// will go away.
UIView* _flutterView;
// Counting the pointers that has started in one touch sequence.
NSInteger _currentTouchPointersCount;
}

- (instancetype)initWithTarget:(id)target flutterView:(UIView*)flutterView {
self = [super initWithTarget:target action:nil];
if (self) {
self.delegate = self;
_flutterView = flutterView;
_currentTouchPointersCount = 0;
}
return self;
}

- (void)touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event {
[_flutterView touchesBegan:touches withEvent:event];
_currentTouchPointersCount += touches.count;
[_flutterView touchesBegan:touches withEvent:event];
}

- (void)touchesMoved:(NSSet*)touches withEvent:(UIEvent*)event {
Expand All @@ -416,11 +436,19 @@ - (void)touchesMoved:(NSSet*)touches withEvent:(UIEvent*)event {

- (void)touchesEnded:(NSSet*)touches withEvent:(UIEvent*)event {
[_flutterView touchesEnded:touches withEvent:event];
self.state = UIGestureRecognizerStateFailed;
_currentTouchPointersCount -= touches.count;
// Touches in one touch sequence are sent to the touchesEnded method separately if different
// fingers stop touching the screen at different time. So one touchesEnded method triggering does
// not necessarially mean the touch sequence has ended. We Only set the state to
// UIGestureRecognizerStateFailed when all the touches in the current touch sequence is ended.
if (_currentTouchPointersCount == 0) {
self.state = UIGestureRecognizerStateFailed;
}
}

- (void)touchesCancelled:(NSSet*)touches withEvent:(UIEvent*)event {
[_flutterView touchesCancelled:touches withEvent:event];
_currentTouchPointersCount = 0;
self.state = UIGestureRecognizerStateFailed;
}

Expand Down

0 comments on commit 36ca574

Please sign in to comment.