diff --git a/React/Fabric/Mounting/ComponentViews/ScrollView/RCTEnhancedScrollView.mm b/React/Fabric/Mounting/ComponentViews/ScrollView/RCTEnhancedScrollView.mm index 2e917090b97..80514c2a54f 100644 --- a/React/Fabric/Mounting/ComponentViews/ScrollView/RCTEnhancedScrollView.mm +++ b/React/Fabric/Mounting/ComponentViews/ScrollView/RCTEnhancedScrollView.mm @@ -37,6 +37,11 @@ self.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever; } + // We intentionally force `UIScrollView`s `semanticContentAttribute` to `LTR` here + // because this attribute affects a position of vertical scrollbar; we don't want this + // scrollbar flip because we also flip it with whole `UIScrollView` flip. + self.semanticContentAttribute = UISemanticContentAttributeForceLeftToRight; + __weak __typeof(self) weakSelf = self; _delegateSplitter = [[RCTGenericDelegateSplitter alloc] initWithDelegateUpdateBlock:^(id delegate) { [weakSelf setPrivateDelegate:delegate]; diff --git a/React/Fabric/Mounting/ComponentViews/ScrollView/RCTScrollViewComponentView.mm b/React/Fabric/Mounting/ComponentViews/ScrollView/RCTScrollViewComponentView.mm index f207e642a96..48816f4c3cf 100644 --- a/React/Fabric/Mounting/ComponentViews/ScrollView/RCTScrollViewComponentView.mm +++ b/React/Fabric/Mounting/ComponentViews/ScrollView/RCTScrollViewComponentView.mm @@ -152,6 +152,20 @@ static void RCTSendPaperScrollEvent_DEPRECATED(UIScrollView *scrollView, NSInteg return concreteComponentDescriptorProvider(); } +- (void)updateLayoutMetrics:(const LayoutMetrics &)layoutMetrics + oldLayoutMetrics:(const LayoutMetrics &)oldLayoutMetrics +{ + [super updateLayoutMetrics:layoutMetrics oldLayoutMetrics:oldLayoutMetrics]; + if (layoutMetrics.layoutDirection != oldLayoutMetrics.layoutDirection) { + CGAffineTransform transform = (layoutMetrics.layoutDirection == LayoutDirection::LeftToRight) + ? CGAffineTransformIdentity + : CGAffineTransformMakeScale(-1, 1); + + _containerView.transform = transform; + _scrollView.transform = transform; + } +} + - (void)updateProps:(Props::Shared const &)props oldProps:(Props::Shared const &)oldProps { const auto &oldScrollViewProps = *std::static_pointer_cast(_props); @@ -279,7 +293,7 @@ static void RCTSendPaperScrollEvent_DEPRECATED(UIScrollView *scrollView, NSInteg } _contentSize = contentSize; - _containerView.frame = CGRect{CGPointZero, contentSize}; + _containerView.frame = CGRect{RCTCGPointFromPoint(data.contentBoundingRect.origin), contentSize}; [self _preserveContentOffsetIfNeededWithBlock:^{ self->_scrollView.contentSize = contentSize; diff --git a/ReactCommon/react/renderer/components/scrollview/ScrollViewState.cpp b/ReactCommon/react/renderer/components/scrollview/ScrollViewState.cpp index 34f59908e11..6f368957a6e 100644 --- a/ReactCommon/react/renderer/components/scrollview/ScrollViewState.cpp +++ b/ReactCommon/react/renderer/components/scrollview/ScrollViewState.cpp @@ -11,7 +11,7 @@ namespace facebook { namespace react { Size ScrollViewState::getContentSize() const { - return Size{contentBoundingRect.getMaxX(), contentBoundingRect.getMaxY()}; + return contentBoundingRect.size; } } // namespace react