forked from facebook/react-native
-
Notifications
You must be signed in to change notification settings - Fork 138
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Fix ghost leave/out events firing due to view recycling
Summary: Changelog: [iOS][Internal] - Fix ghost pointer leave/out events firing due to view recycling on iOS While implementing the properties on the PointerEvent object on iOS I noticed that in certain specific scenarios I was seeing pointerLeave events being fired seemingly without corresponding pointerEvent events and even more strangely, when the pointer wasn't even close to the view in question. After a lot of research I discovered that this was caused by an incompatibility between my strategy of keeping track/identifying views which are being hovered and RN's handling of creating/deleting views on iOS. See on iOS RN has the `RCTComponentViewRegistry` class which manages the creation & deletion of UIViews and adds an optimization of recycling views instead of outright deleting them. This is causing issues with my tracking of which views are hovered because I compare the view's object references which, while accurate towards confirming equality of an underlying UIView — isn't accurate in confirming the equality of views from react's perspective. This diff addresses this issue by adding a simple wrapper class that can be used around the UIViews which stores the view's react ID at initialization time ensuring it doesn't get updated even if the underlying view's react id is. As an additional precaution the wrapper class will also not return the view it's wrapping if their react tags do not match. Reviewed By: lunaleaps Differential Revision: D38546628 fbshipit-source-id: 8b732d52da0e61a5447001e8940e4439f49c6baf
- Loading branch information
1 parent
0149229
commit e532f86
Showing
4 changed files
with
121 additions
and
23 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
/* | ||
* Copyright (c) Meta Platforms, Inc. and affiliates. | ||
* | ||
* This source code is licensed under the MIT license found in the | ||
* LICENSE file in the root directory of this source tree. | ||
*/ | ||
|
||
#import <UIKit/UIKit.h> | ||
|
||
NS_ASSUME_NONNULL_BEGIN | ||
|
||
/** | ||
* Lightweight wrapper class around a UIView with a react tag which registers a | ||
* constant react tag at initialization time for a stable hash and provides the | ||
* udnerlying view to a caller if that underlying view's react tag has not | ||
* changed from the one provided at initalization time (i.e. recycled). | ||
*/ | ||
@interface RCTReactTaggedView : NSObject { | ||
UIView *_view; | ||
NSInteger _tag; | ||
} | ||
|
||
+ (RCTReactTaggedView *)wrap:(UIView *)view; | ||
|
||
- (instancetype)initWithView:(UIView *)view; | ||
- (nullable UIView *)view; | ||
- (NSInteger)tag; | ||
|
||
- (BOOL)isEqual:(id)other; | ||
- (NSUInteger)hash; | ||
|
||
@end | ||
|
||
NS_ASSUME_NONNULL_END |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
/* | ||
* Copyright (c) Meta Platforms, Inc. and affiliates. | ||
* | ||
* This source code is licensed under the MIT license found in the | ||
* LICENSE file in the root directory of this source tree. | ||
*/ | ||
|
||
#import "RCTReactTaggedView.h" | ||
|
||
@implementation RCTReactTaggedView | ||
|
||
+ (RCTReactTaggedView *)wrap:(UIView *)view | ||
{ | ||
return [[RCTReactTaggedView alloc] initWithView:view]; | ||
} | ||
|
||
- (instancetype)initWithView:(UIView *)view | ||
{ | ||
if (self = [super init]) { | ||
_view = view; | ||
_tag = view.tag; | ||
} | ||
return self; | ||
} | ||
|
||
- (nullable UIView *)view | ||
{ | ||
if (_view.tag == _tag) { | ||
return _view; | ||
} | ||
return nil; | ||
} | ||
|
||
- (NSInteger)tag | ||
{ | ||
return _tag; | ||
} | ||
|
||
- (BOOL)isEqual:(id)other | ||
{ | ||
if (other == self) { | ||
return YES; | ||
} | ||
if (!other || ![other isKindOfClass:[self class]]) { | ||
return NO; | ||
} | ||
return _tag == [other tag]; | ||
} | ||
|
||
- (NSUInteger)hash | ||
{ | ||
return _tag; | ||
} | ||
|
||
@end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters