Permalink
Browse files

RCTScrollEvent: get all required values injected rather than accessin…

…g 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
  • Loading branch information...
HeEAaD authored and facebook-github-bot committed Jul 15, 2017
1 parent fac6207 commit 048a9ab10c0ae7ab85679eca39a24f0dc5640dfd
Showing with 41 additions and 17 deletions.
  1. +41 −17 React/Views/RCTScrollView.m
@@ -27,15 +27,23 @@ @interface RCTScrollEvent : NSObject <RCTEvent>
- (instancetype)initWithEventName:(NSString *)eventName
reactTag:(NSNumber *)reactTag
scrollView:(UIScrollView *)scrollView
scrollViewContentOffset:(CGPoint)scrollViewContentOffset
scrollViewContentInset:(UIEdgeInsets)scrollViewContentInset
scrollViewContentSize:(CGSize)scrollViewContentSize
scrollViewFrame:(CGRect)scrollViewFrame
scrollViewZoomScale:(CGFloat)scrollViewZoomScale
userData:(NSDictionary *)userData
coalescingKey:(uint16_t)coalescingKey NS_DESIGNATED_INITIALIZER;
@end
@implementation RCTScrollEvent
{
UIScrollView *_scrollView;
CGPoint _scrollViewContentOffset;
UIEdgeInsets _scrollViewContentInset;
CGSize _scrollViewContentSize;
CGRect _scrollViewFrame;
CGFloat _scrollViewZoomScale;
NSDictionary *_userData;
uint16_t _coalescingKey;
}
@@ -45,7 +53,11 @@ @implementation RCTScrollEvent
- (instancetype)initWithEventName:(NSString *)eventName
reactTag:(NSNumber *)reactTag
scrollView:(UIScrollView *)scrollView
scrollViewContentOffset:(CGPoint)scrollViewContentOffset
scrollViewContentInset:(UIEdgeInsets)scrollViewContentInset
scrollViewContentSize:(CGSize)scrollViewContentSize
scrollViewFrame:(CGRect)scrollViewFrame
scrollViewZoomScale:(CGFloat)scrollViewZoomScale
userData:(NSDictionary *)userData
coalescingKey:(uint16_t)coalescingKey
{
@@ -54,7 +66,11 @@ - (instancetype)initWithEventName:(NSString *)eventName
if ((self = [super init])) {
_eventName = [eventName copy];
_viewTag = reactTag;
_scrollView = scrollView;
_scrollViewContentOffset = scrollViewContentOffset;
_scrollViewContentInset = scrollViewContentInset;
_scrollViewContentSize = scrollViewContentSize;
_scrollViewFrame = scrollViewFrame;
_scrollViewZoomScale = scrollViewZoomScale;
_userData = userData;
_coalescingKey = coalescingKey;
}
@@ -72,24 +88,24 @@ - (NSDictionary *)body
{
NSDictionary *body = @{
@"contentOffset": @{
@"x": @(_scrollView.contentOffset.x),
@"y": @(_scrollView.contentOffset.y)
@"x": @(_scrollViewContentOffset.x),
@"y": @(_scrollViewContentOffset.y)
},
@"contentInset": @{
@"top": @(_scrollView.contentInset.top),
@"left": @(_scrollView.contentInset.left),
@"bottom": @(_scrollView.contentInset.bottom),
@"right": @(_scrollView.contentInset.right)
@"top": @(_scrollViewContentInset.top),
@"left": @(_scrollViewContentInset.left),
@"bottom": @(_scrollViewContentInset.bottom),
@"right": @(_scrollViewContentInset.right)
},
@"contentSize": @{
@"width": @(_scrollView.contentSize.width),
@"height": @(_scrollView.contentSize.height)
@"width": @(_scrollViewContentSize.width),
@"height": @(_scrollViewContentSize.height)
},
@"layoutMeasurement": @{
@"width": @(_scrollView.frame.size.width),
@"height": @(_scrollView.frame.size.height)
@"width": @(_scrollViewFrame.size.width),
@"height": @(_scrollViewFrame.size.height)
},
@"zoomScale": @(_scrollView.zoomScale ?: 1),
@"zoomScale": @(_scrollViewZoomScale ?: 1),
};
if (_userData) {
@@ -893,7 +909,11 @@ - (void)sendScrollEventWithName:(NSString *)eventName
}
RCTScrollEvent *scrollEvent = [[RCTScrollEvent alloc] initWithEventName:eventName
reactTag:self.reactTag
scrollView:scrollView
scrollViewContentOffset:scrollView.contentOffset
scrollViewContentInset:scrollView.contentInset
scrollViewContentSize:scrollView.contentSize
scrollViewFrame:scrollView.frame
scrollViewZoomScale:scrollView.zoomScale
userData:userData
coalescingKey:_coalescingKey];
[_eventDispatcher sendEvent:scrollEvent];
@@ -909,7 +929,11 @@ - (void)sendFakeScrollEvent:(NSNumber *)reactTag
NSString *eventName = NSStringFromSelector(@selector(onScroll));
RCTScrollEvent *fakeScrollEvent = [[RCTScrollEvent alloc] initWithEventName:eventName
reactTag:reactTag
scrollView:nil
scrollViewContentOffset:CGPointZero
scrollViewContentInset:UIEdgeInsetsZero
scrollViewContentSize:CGSizeZero
scrollViewFrame:CGRectZero
scrollViewZoomScale:0
userData:nil
coalescingKey:0];
[self sendEvent:fakeScrollEvent];

0 comments on commit 048a9ab

Please sign in to comment.