mirror of
https://github.com/status-im/react-native.git
synced 2025-02-22 06:08:24 +00:00
Fabric: Proper implementation -[RCTSurfaceTouchHandler reset]
Summary: Apparently, if a gesture recognizer got 'reset', OS does not call `touchesCancelled:` method, so we have to do it manually. To implement this we have to split `_dispatchTouches:eventType:` into two methods: the first converts Objective-C touches to C++ touches, the second consumes that. We have to do this because during reset we don't have a collection of UIKit touches. Reviewed By: mdvacca Differential Revision: D13072807 fbshipit-source-id: 677e2febf9f96dcdfaadfadf5b9ab3893f93e796
This commit is contained in:
parent
868406dbec
commit
560652cfe8
@ -209,16 +209,26 @@ RCT_NOT_IMPLEMENTED(- (instancetype)initWithTarget:(id)target action:(SEL)action
|
||||
}
|
||||
}
|
||||
|
||||
- (void)_dispatchTouches:(NSSet<UITouch *> *)touches eventType:(RCTTouchEventType)eventType
|
||||
- (std::vector<ActiveTouch>)_activeTouchesFromTouches:(NSSet<UITouch *> *)touches
|
||||
{
|
||||
std::vector<ActiveTouch> activeTouches;
|
||||
activeTouches.reserve(touches.count);
|
||||
|
||||
for (UITouch *touch in touches) {
|
||||
activeTouches.push_back(_activeTouches.at(touch));
|
||||
}
|
||||
|
||||
return activeTouches;
|
||||
}
|
||||
|
||||
- (void)_dispatchActiveTouches:(std::vector<ActiveTouch>)activeTouches eventType:(RCTTouchEventType)eventType
|
||||
{
|
||||
TouchEvent event = {};
|
||||
std::unordered_set<ActiveTouch, ActiveTouch::Hasher, ActiveTouch::Comparator> changedActiveTouches = {};
|
||||
std::unordered_set<SharedTouchEventEmitter> uniqueEventEmitter = {};
|
||||
BOOL isEndishEventType = eventType == RCTTouchEventTypeTouchEnd || eventType == RCTTouchEventTypeTouchCancel;
|
||||
|
||||
for (UITouch *touch in touches) {
|
||||
const auto &activeTouch = _activeTouches[touch];
|
||||
|
||||
for (const auto &activeTouch : activeTouches) {
|
||||
if (!activeTouch.eventEmitter) {
|
||||
continue;
|
||||
}
|
||||
@ -276,7 +286,8 @@ RCT_NOT_IMPLEMENTED(- (instancetype)initWithTarget:(id)target action:(SEL)action
|
||||
[super touchesBegan:touches withEvent:event];
|
||||
|
||||
[self _registerTouches:touches];
|
||||
[self _dispatchTouches:touches eventType:RCTTouchEventTypeTouchStart];
|
||||
[self _dispatchActiveTouches:[self _activeTouchesFromTouches:touches]
|
||||
eventType:RCTTouchEventTypeTouchStart];
|
||||
|
||||
if (self.state == UIGestureRecognizerStatePossible) {
|
||||
self.state = UIGestureRecognizerStateBegan;
|
||||
@ -290,7 +301,8 @@ RCT_NOT_IMPLEMENTED(- (instancetype)initWithTarget:(id)target action:(SEL)action
|
||||
[super touchesMoved:touches withEvent:event];
|
||||
|
||||
[self _updateTouches:touches];
|
||||
[self _dispatchTouches:touches eventType:RCTTouchEventTypeTouchMove];
|
||||
[self _dispatchActiveTouches:[self _activeTouchesFromTouches:touches]
|
||||
eventType:RCTTouchEventTypeTouchMove];
|
||||
|
||||
self.state = UIGestureRecognizerStateChanged;
|
||||
}
|
||||
@ -300,7 +312,8 @@ RCT_NOT_IMPLEMENTED(- (instancetype)initWithTarget:(id)target action:(SEL)action
|
||||
[super touchesEnded:touches withEvent:event];
|
||||
|
||||
[self _updateTouches:touches];
|
||||
[self _dispatchTouches:touches eventType:RCTTouchEventTypeTouchEnd];
|
||||
[self _dispatchActiveTouches:[self _activeTouchesFromTouches:touches]
|
||||
eventType:RCTTouchEventTypeTouchEnd];
|
||||
[self _unregisterTouches:touches];
|
||||
|
||||
if (AllTouchesAreCancelledOrEnded(event.allTouches)) {
|
||||
@ -315,7 +328,8 @@ RCT_NOT_IMPLEMENTED(- (instancetype)initWithTarget:(id)target action:(SEL)action
|
||||
[super touchesCancelled:touches withEvent:event];
|
||||
|
||||
[self _updateTouches:touches];
|
||||
[self _dispatchTouches:touches eventType:RCTTouchEventTypeTouchCancel];
|
||||
[self _dispatchActiveTouches:[self _activeTouchesFromTouches:touches]
|
||||
eventType:RCTTouchEventTypeTouchCancel];
|
||||
[self _unregisterTouches:touches];
|
||||
|
||||
if (AllTouchesAreCancelledOrEnded(event.allTouches)) {
|
||||
@ -327,10 +341,23 @@ RCT_NOT_IMPLEMENTED(- (instancetype)initWithTarget:(id)target action:(SEL)action
|
||||
|
||||
- (void)reset
|
||||
{
|
||||
// Technically, `_activeTouches` must be already empty at this point,
|
||||
// but just to be sure, we clear it explicitly.
|
||||
_activeTouches.clear();
|
||||
_identifierPool.reset();
|
||||
[super reset];
|
||||
|
||||
if (_activeTouches.size() != 0) {
|
||||
std::vector<ActiveTouch> activeTouches;
|
||||
activeTouches.reserve(_activeTouches.size());
|
||||
|
||||
for (auto const &pair : _activeTouches) {
|
||||
activeTouches.push_back(pair.second);
|
||||
}
|
||||
|
||||
[self _dispatchActiveTouches:activeTouches
|
||||
eventType:RCTTouchEventTypeTouchCancel];
|
||||
|
||||
// Force-unregistering all the touches.
|
||||
_activeTouches.clear();
|
||||
_identifierPool.reset();
|
||||
}
|
||||
}
|
||||
|
||||
- (BOOL)canPreventGestureRecognizer:(__unused UIGestureRecognizer *)preventedGestureRecognizer
|
||||
|
Loading…
x
Reference in New Issue
Block a user