Skip to content

Commit 048a9ab

Browse files
Steffen Matthischkefacebook-github-bot
authored andcommitted
RCTScrollEvent: get all required values injected rather than accessing the scroll view
Summary: This PR fixes #15006 by removing all UI API calls from RCTScrollEvent. `-[RCTScrollEvent arguments]` can now be called from a background thread. The Main Thread Checker of Xcode 9 will not any longer produce runtime issues when calling this method. 1. create a React Native (version: this PR) project with a scroll view 2. open it in Xcode 9 3. launch it 4. scroll the scroll view 5. observe the runtime issues in Xcode. There should not contain "UI API called from background thread"-issues. I verified my changes on this branch: https://github.com/HeEAaD/Demo-ReactNative-UI-not-on-main-thread/tree/fix <!-- Thank you for sending the PR! If you changed any code, please provide us with clear instructions on how you verified your changes work. In other words, a test plan is *required*. Bonus points for screenshots and videos! Please read the Contribution Guidelines at https://github.com/facebook/react-native/blob/master/CONTRIBUTING.md to learn more about contributing to React Native. Happy contributing! --> Closes #15008 Differential Revision: D5424734 Pulled By: shergin fbshipit-source-id: 56beec2d7603ea6782d55622567509f3758a4517
1 parent fac6207 commit 048a9ab

File tree

1 file changed

+41
-17
lines changed

1 file changed

+41
-17
lines changed

React/Views/RCTScrollView.m

Lines changed: 41 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -27,15 +27,23 @@ @interface RCTScrollEvent : NSObject <RCTEvent>
2727

2828
- (instancetype)initWithEventName:(NSString *)eventName
2929
reactTag:(NSNumber *)reactTag
30-
scrollView:(UIScrollView *)scrollView
30+
scrollViewContentOffset:(CGPoint)scrollViewContentOffset
31+
scrollViewContentInset:(UIEdgeInsets)scrollViewContentInset
32+
scrollViewContentSize:(CGSize)scrollViewContentSize
33+
scrollViewFrame:(CGRect)scrollViewFrame
34+
scrollViewZoomScale:(CGFloat)scrollViewZoomScale
3135
userData:(NSDictionary *)userData
3236
coalescingKey:(uint16_t)coalescingKey NS_DESIGNATED_INITIALIZER;
3337

3438
@end
3539

3640
@implementation RCTScrollEvent
3741
{
38-
UIScrollView *_scrollView;
42+
CGPoint _scrollViewContentOffset;
43+
UIEdgeInsets _scrollViewContentInset;
44+
CGSize _scrollViewContentSize;
45+
CGRect _scrollViewFrame;
46+
CGFloat _scrollViewZoomScale;
3947
NSDictionary *_userData;
4048
uint16_t _coalescingKey;
4149
}
@@ -45,7 +53,11 @@ @implementation RCTScrollEvent
4553

4654
- (instancetype)initWithEventName:(NSString *)eventName
4755
reactTag:(NSNumber *)reactTag
48-
scrollView:(UIScrollView *)scrollView
56+
scrollViewContentOffset:(CGPoint)scrollViewContentOffset
57+
scrollViewContentInset:(UIEdgeInsets)scrollViewContentInset
58+
scrollViewContentSize:(CGSize)scrollViewContentSize
59+
scrollViewFrame:(CGRect)scrollViewFrame
60+
scrollViewZoomScale:(CGFloat)scrollViewZoomScale
4961
userData:(NSDictionary *)userData
5062
coalescingKey:(uint16_t)coalescingKey
5163
{
@@ -54,7 +66,11 @@ - (instancetype)initWithEventName:(NSString *)eventName
5466
if ((self = [super init])) {
5567
_eventName = [eventName copy];
5668
_viewTag = reactTag;
57-
_scrollView = scrollView;
69+
_scrollViewContentOffset = scrollViewContentOffset;
70+
_scrollViewContentInset = scrollViewContentInset;
71+
_scrollViewContentSize = scrollViewContentSize;
72+
_scrollViewFrame = scrollViewFrame;
73+
_scrollViewZoomScale = scrollViewZoomScale;
5874
_userData = userData;
5975
_coalescingKey = coalescingKey;
6076
}
@@ -72,24 +88,24 @@ - (NSDictionary *)body
7288
{
7389
NSDictionary *body = @{
7490
@"contentOffset": @{
75-
@"x": @(_scrollView.contentOffset.x),
76-
@"y": @(_scrollView.contentOffset.y)
91+
@"x": @(_scrollViewContentOffset.x),
92+
@"y": @(_scrollViewContentOffset.y)
7793
},
7894
@"contentInset": @{
79-
@"top": @(_scrollView.contentInset.top),
80-
@"left": @(_scrollView.contentInset.left),
81-
@"bottom": @(_scrollView.contentInset.bottom),
82-
@"right": @(_scrollView.contentInset.right)
95+
@"top": @(_scrollViewContentInset.top),
96+
@"left": @(_scrollViewContentInset.left),
97+
@"bottom": @(_scrollViewContentInset.bottom),
98+
@"right": @(_scrollViewContentInset.right)
8399
},
84100
@"contentSize": @{
85-
@"width": @(_scrollView.contentSize.width),
86-
@"height": @(_scrollView.contentSize.height)
101+
@"width": @(_scrollViewContentSize.width),
102+
@"height": @(_scrollViewContentSize.height)
87103
},
88104
@"layoutMeasurement": @{
89-
@"width": @(_scrollView.frame.size.width),
90-
@"height": @(_scrollView.frame.size.height)
105+
@"width": @(_scrollViewFrame.size.width),
106+
@"height": @(_scrollViewFrame.size.height)
91107
},
92-
@"zoomScale": @(_scrollView.zoomScale ?: 1),
108+
@"zoomScale": @(_scrollViewZoomScale ?: 1),
93109
};
94110

95111
if (_userData) {
@@ -893,7 +909,11 @@ - (void)sendScrollEventWithName:(NSString *)eventName
893909
}
894910
RCTScrollEvent *scrollEvent = [[RCTScrollEvent alloc] initWithEventName:eventName
895911
reactTag:self.reactTag
896-
scrollView:scrollView
912+
scrollViewContentOffset:scrollView.contentOffset
913+
scrollViewContentInset:scrollView.contentInset
914+
scrollViewContentSize:scrollView.contentSize
915+
scrollViewFrame:scrollView.frame
916+
scrollViewZoomScale:scrollView.zoomScale
897917
userData:userData
898918
coalescingKey:_coalescingKey];
899919
[_eventDispatcher sendEvent:scrollEvent];
@@ -909,7 +929,11 @@ - (void)sendFakeScrollEvent:(NSNumber *)reactTag
909929
NSString *eventName = NSStringFromSelector(@selector(onScroll));
910930
RCTScrollEvent *fakeScrollEvent = [[RCTScrollEvent alloc] initWithEventName:eventName
911931
reactTag:reactTag
912-
scrollView:nil
932+
scrollViewContentOffset:CGPointZero
933+
scrollViewContentInset:UIEdgeInsetsZero
934+
scrollViewContentSize:CGSizeZero
935+
scrollViewFrame:CGRectZero
936+
scrollViewZoomScale:0
913937
userData:nil
914938
coalescingKey:0];
915939
[self sendEvent:fakeScrollEvent];

0 commit comments

Comments
 (0)