From 9ca460f06405db85d0df60cbe53c304c9127c3bf Mon Sep 17 00:00:00 2001 From: Samuel Susla Date: Wed, 16 Jun 2021 11:02:33 -0700 Subject: [PATCH] Take RTL into account in scrollTo view command Summary: Changelog: [internal] ScrollView's `scrollTo` command doesn't work in RTL. It sets the offset from left of the screen instead of right. This diff fixes this for Fabric only. Reviewed By: JoshuaGross Differential Revision: D29164056 fbshipit-source-id: f685d3e013f474f9b445112333d8f5ad7ed36ea7 --- .../ScrollView/RCTScrollViewComponentView.mm | 54 ++++++++++--------- 1 file changed, 29 insertions(+), 25 deletions(-) diff --git a/React/Fabric/Mounting/ComponentViews/ScrollView/RCTScrollViewComponentView.mm b/React/Fabric/Mounting/ComponentViews/ScrollView/RCTScrollViewComponentView.mm index 535a8c6c1c4..bbd855bdecb 100644 --- a/React/Fabric/Mounting/ComponentViews/ScrollView/RCTScrollViewComponentView.mm +++ b/React/Fabric/Mounting/ComponentViews/ScrollView/RCTScrollViewComponentView.mm @@ -563,31 +563,29 @@ static void RCTSendPaperScrollEvent_DEPRECATED(UIScrollView *scrollView, NSInteg - (void)scrollTo:(double)x y:(double)y animated:(BOOL)animated { CGPoint offset = CGPointMake(x, y); - if (!CGPointEqualToPoint(_scrollView.contentOffset, offset)) { - CGRect maxRect = CGRectMake( - fmin(-_scrollView.contentInset.left, 0), - fmin(-_scrollView.contentInset.top, 0), - fmax( - _scrollView.contentSize.width - _scrollView.bounds.size.width + _scrollView.contentInset.right + - fmax(_scrollView.contentInset.left, 0), - 0.01), - 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 + CGRect maxRect = CGRectMake( + fmin(-_scrollView.contentInset.left, 0), + fmin(-_scrollView.contentInset.top, 0), + fmax( + _scrollView.contentSize.width - _scrollView.bounds.size.width + _scrollView.contentInset.right + + fmax(_scrollView.contentInset.left, 0), + 0.01), + 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 - const auto &props = *std::static_pointer_cast(_props); - if (!CGRectContainsPoint(maxRect, offset) && !props.scrollToOverflowEnabled) { - CGFloat localX = fmax(offset.x, CGRectGetMinX(maxRect)); - localX = fmin(localX, CGRectGetMaxX(maxRect)); - CGFloat localY = fmax(offset.y, CGRectGetMinY(maxRect)); - localY = fmin(localY, CGRectGetMaxY(maxRect)); - offset = CGPointMake(localX, localY); - } - - [self _forceDispatchNextScrollEvent]; - [_scrollView setContentOffset:offset animated:animated]; + const auto &props = *std::static_pointer_cast(_props); + if (!CGRectContainsPoint(maxRect, offset) && !props.scrollToOverflowEnabled) { + CGFloat localX = fmax(offset.x, CGRectGetMinX(maxRect)); + localX = fmin(localX, CGRectGetMaxX(maxRect)); + CGFloat localY = fmax(offset.y, CGRectGetMinY(maxRect)); + localY = fmin(localY, CGRectGetMaxY(maxRect)); + offset = CGPointMake(localX, localY); } + + [self _forceDispatchNextScrollEvent]; + [self scrollToOffset:offset animated:animated]; } - (void)scrollToEnd:(BOOL)animated @@ -602,7 +600,7 @@ static void RCTSendPaperScrollEvent_DEPRECATED(UIScrollView *scrollView, NSInteg offset = CGPointMake(0, fmax(offsetY, 0)); } - [_scrollView setContentOffset:offset animated:animated]; + [self scrollToOffset:offset animated:animated]; } #pragma mark - Child views mounting @@ -707,7 +705,13 @@ static void RCTSendPaperScrollEvent_DEPRECATED(UIScrollView *scrollView, NSInteg - (void)scrollToOffset:(CGPoint)offset animated:(BOOL)animated { [self _forceDispatchNextScrollEvent]; - [self.scrollView setContentOffset:offset animated:animated]; + + if (_layoutMetrics.layoutDirection == LayoutDirection::RightToLeft) { + // Adjusting offset.x in right to left layout direction. + offset.x = self.contentSize.width - _scrollView.frame.size.width - offset.x; + } + + [_scrollView setContentOffset:offset animated:animated]; } - (void)zoomToRect:(CGRect)rect animated:(BOOL)animated