From 30aad14e7703510e7d66c97e3eef86d03a35da61 Mon Sep 17 00:00:00 2001 From: Emilio Date: Thu, 19 Dec 2019 15:27:50 -0800 Subject: [PATCH] tapping on iOS status bar should scroll inverted ScrollViews to their top (#27574) Summary: React Native ScrollViews are flipped upside down when the prop inverted is set to true. This is the root of a bug: tapping on the status bar in iOS should scroll the Flatlist up to the top but currently it does to the bottom. The solution proposed is to detect natively if the ScrollView is inverted, on such case, prevent it from scrolling it to the beginning of the ScrollView (as a non-inverted ScrollView would do) and force a scroll to the end of it. I've been careful enough not to force the scroll if the user explicitly selected not to do it or if it's happening in a nested ScrollView, as it is the default behaviour in iOS. Fixes https://github.com/facebook/react-native/issues/21126 ## Changelog [iOS] [Fixed] - Inverted ScrollViews scroll to their bottom when the status bar is pressed Pull Request resolved: https://github.com/facebook/react-native/pull/27574 Test Plan: - on iOS, add a ScrollView and put enough content to overflow the screen size so it can be scrolled - add the prop `inverted={true}` to the ScrollView - go to the screen the Scrollview is in and press the status bar - it should scroll to top (previously it scrolled to the bottom) ![v](https://user-images.githubusercontent.com/807710/71188640-a0ac6680-2281-11ea-91a7-d1e46aba8b14.gif) Differential Revision: D19185270 Pulled By: hramos fbshipit-source-id: 5445093ff38f4ba4082f1d883d8ed087e9565eaf --- React/Views/ScrollView/RCTScrollView.h | 1 + React/Views/ScrollView/RCTScrollView.m | 6 ++++++ React/Views/ScrollView/RCTScrollViewManager.m | 1 + 3 files changed, 8 insertions(+) diff --git a/React/Views/ScrollView/RCTScrollView.h b/React/Views/ScrollView/RCTScrollView.h index 8084a91a943..d5ac000284e 100644 --- a/React/Views/ScrollView/RCTScrollView.h +++ b/React/Views/ScrollView/RCTScrollView.h @@ -51,6 +51,7 @@ @property (nonatomic, assign) BOOL snapToStart; @property (nonatomic, assign) BOOL snapToEnd; @property (nonatomic, copy) NSString *snapToAlignment; +@property (nonatomic, assign) BOOL inverted; // NOTE: currently these event props are only declared so we can export the // event names to JS - we don't call the blocks directly because scroll events diff --git a/React/Views/ScrollView/RCTScrollView.m b/React/Views/ScrollView/RCTScrollView.m index 4d6c1d5e9de..4b4d46a50a1 100644 --- a/React/Views/ScrollView/RCTScrollView.m +++ b/React/Views/ScrollView/RCTScrollView.m @@ -829,6 +829,12 @@ RCT_SCROLL_EVENT_HANDLER(scrollViewDidScrollToTop, onScrollToTop) return NO; } } + + if (self.inverted) { + [self scrollToEnd:YES]; + return NO; + } + return YES; } diff --git a/React/Views/ScrollView/RCTScrollViewManager.m b/React/Views/ScrollView/RCTScrollViewManager.m index ba0005a730f..06e5ff82a31 100644 --- a/React/Views/ScrollView/RCTScrollViewManager.m +++ b/React/Views/ScrollView/RCTScrollViewManager.m @@ -98,6 +98,7 @@ RCT_EXPORT_VIEW_PROPERTY(onScrollEndDrag, RCTDirectEventBlock) RCT_EXPORT_VIEW_PROPERTY(onMomentumScrollBegin, RCTDirectEventBlock) RCT_EXPORT_VIEW_PROPERTY(onMomentumScrollEnd, RCTDirectEventBlock) RCT_EXPORT_VIEW_PROPERTY(DEPRECATED_sendUpdatedChildFrames, BOOL) +RCT_EXPORT_VIEW_PROPERTY(inverted, BOOL) #if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 110000 /* __IPHONE_11_0 */ RCT_EXPORT_VIEW_PROPERTY(contentInsetAdjustmentBehavior, UIScrollViewContentInsetAdjustmentBehavior) #endif