From 702ff6d1cdc378815ff1beb563c2c8cc4f30585c Mon Sep 17 00:00:00 2001 From: yogevbd Date: Mon, 27 Apr 2020 13:29:41 -0700 Subject: [PATCH] iOS: Fix refreshControl layouting (#28236) Summary: In `react-native-navigation` we allow the usage of native iOS navigationBar **largeTitle** which cause the title to "jump" when pulling to refresh. We found that the layout calculations of the refreshControl element mess up the system behaviour. ## Changelog [iOS] [Fixed] - Fix refreshControl messes up navigationBar largeTitles Pull Request resolved: https://github.com/facebook/react-native/pull/28236 Test Plan: ### Before the fix: ![before](https://user-images.githubusercontent.com/10794586/75991307-f7c7ec00-5efe-11ea-8cd9-ab8c3fbe1dc1.gif) ### And after: ![after](https://user-images.githubusercontent.com/10794586/75990618-d9152580-5efd-11ea-8c72-5deb6d83a840.gif) ### How it looks like with react-native init app after the fix: ![ezgif com-video-to-gif (4)](https://user-images.githubusercontent.com/10794586/77253369-54970680-6c62-11ea-9ad6-3265e23044e6.gif) Differential Revision: D20587945 Pulled By: shergin fbshipit-source-id: 94f560b17e367f4ef5e789f40c052396949b51a3 --- React/Views/RefreshControl/RCTRefreshControl.m | 6 ------ React/Views/ScrollView/RCTScrollView.m | 18 ++++-------------- 2 files changed, 4 insertions(+), 20 deletions(-) diff --git a/React/Views/RefreshControl/RCTRefreshControl.m b/React/Views/RefreshControl/RCTRefreshControl.m index 428a5e7fa40..419535bcb46 100644 --- a/React/Views/RefreshControl/RCTRefreshControl.m +++ b/React/Views/RefreshControl/RCTRefreshControl.m @@ -41,12 +41,6 @@ RCT_NOT_IMPLEMENTED(-(instancetype)initWithCoder : (NSCoder *)aDecoder) { [super layoutSubviews]; - // Fix for bug #7976 - // TODO: Remove when updating to use iOS 10 refreshControl UIScrollView prop. - if (self.backgroundColor == nil) { - self.backgroundColor = [UIColor clearColor]; - } - // If the control is refreshing when mounted we need to call // beginRefreshing in layoutSubview or it doesn't work. if (_currentRefreshingState && _isInitialRender) { diff --git a/React/Views/ScrollView/RCTScrollView.m b/React/Views/ScrollView/RCTScrollView.m index 56d63505b9e..bb49c8d7363 100644 --- a/React/Views/ScrollView/RCTScrollView.m +++ b/React/Views/ScrollView/RCTScrollView.m @@ -32,7 +32,7 @@ @property (nonatomic, assign) BOOL centerContent; #if !TARGET_OS_TV -@property (nonatomic, strong) UIView *customRefreshControl; +@property (nonatomic, strong) UIRefreshControl *customRefreshControl; @property (nonatomic, assign) BOOL pinchGestureEnabled; #endif @@ -224,13 +224,13 @@ } #if !TARGET_OS_TV -- (void)setCustomRefreshControl:(UIView *)refreshControl +- (void)setCustomRefreshControl:(UIRefreshControl *)refreshControl { if (_customRefreshControl) { [_customRefreshControl removeFromSuperview]; } _customRefreshControl = refreshControl; - [self addSubview:_customRefreshControl]; + self.refreshControl = refreshControl; } - (void)setPinchGestureEnabled:(BOOL)pinchGestureEnabled @@ -344,7 +344,7 @@ static inline void RCTApplyTransformationAccordingLayoutDirection( [super insertReactSubview:view atIndex:atIndex]; #if !TARGET_OS_TV if ([view conformsToProtocol:@protocol(RCTCustomRefreshContolProtocol)]) { - [_scrollView setCustomRefreshControl:(UIView *)view]; + [_scrollView setCustomRefreshControl:(UIRefreshControl *)view]; if (![view isKindOfClass:[UIRefreshControl class]] && [view conformsToProtocol:@protocol(UIScrollViewDelegate)]) { [self addScrollListener:(UIView *)view]; } @@ -418,16 +418,6 @@ static inline void RCTApplyTransformationAccordingLayoutDirection( [super layoutSubviews]; RCTAssert(self.subviews.count == 1, @"we should only have exactly one subview"); RCTAssert([self.subviews lastObject] == _scrollView, @"our only subview should be a scrollview"); - -#if !TARGET_OS_TV - // Adjust the refresh control frame if the scrollview layout changes. - UIView *refreshControl = _scrollView.customRefreshControl; - if (refreshControl && refreshControl.isRefreshing) { - refreshControl.frame = - (CGRect){_scrollView.contentOffset, {_scrollView.frame.size.width, refreshControl.frame.size.height}}; - } -#endif - [self updateClippedSubviews]; }