From e3ac3293d93c0c5899f9dafb0cc7cdea13aa53e7 Mon Sep 17 00:00:00 2001 From: Craig_Martin Date: Wed, 3 Apr 2019 16:16:34 -0700 Subject: [PATCH] Add scrollToOverflowEnabled prop to ScrollView (#24296) Summary: ScrollView's scrollTo behavior on iOS was recently changed to limit the offset to the content size plus any content inset (see #23427). This departure from the old behavior created UI issues for anyone that is using the over-scroll ability for the purpose of positioning elements at specific coordinates on the screen. Examples include using this behavior to position TextInputs above the virtual keyboard programmatically when focused or moving drop down elements positioned near the bottom of the content toward the top of the screen when selected to show a larger absolutely positioned item list. Default behavior does not change and this is an "opt-in" type of prop to re-enable the old behavior. [iOS] [Added] - Added scrollToOverflowEnabled prop to ScrollView Pull Request resolved: https://github.com/facebook/react-native/pull/24296 Differential Revision: D14762619 Pulled By: cpojer fbshipit-source-id: d2a552b5cb321d52e8ea4116327bf9ec647a3aae --- Libraries/Components/ScrollView/ScrollView.js | 6 ++++++ React/Views/ScrollView/RCTScrollView.h | 1 + React/Views/ScrollView/RCTScrollView.m | 2 +- React/Views/ScrollView/RCTScrollViewManager.m | 1 + 4 files changed, 9 insertions(+), 1 deletion(-) diff --git a/Libraries/Components/ScrollView/ScrollView.js b/Libraries/Components/ScrollView/ScrollView.js index c237e0a6a4a..6a9ce2c7fed 100644 --- a/Libraries/Components/ScrollView/ScrollView.js +++ b/Libraries/Components/ScrollView/ScrollView.js @@ -210,6 +210,12 @@ type IOSProps = $ReadOnly<{| * @platform ios */ scrollIndicatorInsets?: ?EdgeInsetsProp, + /** + * When true, the scroll view can be programmatically scrolled beyond its + * content size. The default value is false. + * @platform ios + */ + scrollToOverflowEnabled?: ?boolean, /** * When true, the scroll view scrolls to top when the status bar is tapped. * The default value is true. diff --git a/React/Views/ScrollView/RCTScrollView.h b/React/Views/ScrollView/RCTScrollView.h index 3404422c7b0..6ef40fa8408 100644 --- a/React/Views/ScrollView/RCTScrollView.h +++ b/React/Views/ScrollView/RCTScrollView.h @@ -44,6 +44,7 @@ @property (nonatomic, assign) NSTimeInterval scrollEventThrottle; @property (nonatomic, assign) BOOL centerContent; @property (nonatomic, copy) NSDictionary *maintainVisibleContentPosition; +@property (nonatomic, assign) BOOL scrollToOverflowEnabled; @property (nonatomic, assign) int snapToInterval; @property (nonatomic, copy) NSArray *snapToOffsets; @property (nonatomic, assign) BOOL snapToStart; diff --git a/React/Views/ScrollView/RCTScrollView.m b/React/Views/ScrollView/RCTScrollView.m index fde91c92d3c..46b2a69b489 100644 --- a/React/Views/ScrollView/RCTScrollView.m +++ b/React/Views/ScrollView/RCTScrollView.m @@ -594,7 +594,7 @@ static inline void RCTApplyTransformationAccordingLayoutDirection(UIView *view, fmax(_scrollView.contentSize.height - _scrollView.bounds.size.height + _scrollView.contentInset.bottom + fmax(_scrollView.contentInset.top, 0), 0.01)); // Make width and height greater than 0 // Ensure at least one scroll event will fire _allowNextScrollNoMatterWhat = YES; - if (!CGRectContainsPoint(maxRect, offset)) { + if (!CGRectContainsPoint(maxRect, offset) && !self.scrollToOverflowEnabled) { CGFloat x = fmax(offset.x, CGRectGetMinX(maxRect)); x = fmin(x, CGRectGetMaxX(maxRect)); CGFloat y = fmax(offset.y, CGRectGetMinY(maxRect)); diff --git a/React/Views/ScrollView/RCTScrollViewManager.m b/React/Views/ScrollView/RCTScrollViewManager.m index 6494d52f48f..a9714f8dfe9 100644 --- a/React/Views/ScrollView/RCTScrollViewManager.m +++ b/React/Views/ScrollView/RCTScrollViewManager.m @@ -80,6 +80,7 @@ RCT_EXPORT_VIEW_PROPERTY(scrollEventThrottle, NSTimeInterval) RCT_EXPORT_VIEW_PROPERTY(zoomScale, CGFloat) RCT_EXPORT_VIEW_PROPERTY(contentInset, UIEdgeInsets) RCT_EXPORT_VIEW_PROPERTY(scrollIndicatorInsets, UIEdgeInsets) +RCT_EXPORT_VIEW_PROPERTY(scrollToOverflowEnabled, BOOL) RCT_EXPORT_VIEW_PROPERTY(snapToInterval, int) RCT_EXPORT_VIEW_PROPERTY(snapToOffsets, NSArray) RCT_EXPORT_VIEW_PROPERTY(snapToStart, BOOL)