Skip to content

Commit b44e183

Browse files
sammy-SCfacebook-github-bot
authored andcommitted
fix crash in adjustForMaintainVisibleContentPosition (#53208)
Summary: Pull Request resolved: #53208 changelog: [internal] When Fabric View Culling is enabled together with immediate state update, it may lead to a crash inside of `[RCTScrollViewComponentView _adjustForMaintainVisibleContentPosition]`. When doing immediate state update, we can avoid calling `[RCTScrollViewComponentView _adjustForMaintainVisibleContentPosition]` altogether to avoid the crash. Reviewed By: lenaic Differential Revision: D80000362 fbshipit-source-id: 123b70aa31edb14a99bb968648eb8b8aac84afb6
1 parent 4ee326f commit b44e183

1 file changed

Lines changed: 14 additions & 4 deletions

File tree

packages/react-native/React/Fabric/Mounting/ComponentViews/ScrollView/RCTScrollViewComponentView.mm

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,10 @@ @implementation RCTScrollViewComponentView {
119119
// Once an accessibility API is used, view culling will be disabled for the entire session.
120120
BOOL _isAccessibilityAPIUsed;
121121

122+
// Flag to temporarily disable maintainVisibleContentPosition adjustments during immediate state updates
123+
// to prevent conflicts between immediate content offset updates and visible content position logic
124+
BOOL _avoidAdjustmentForMaintainVisibleContentPosition;
125+
122126
RCTVirtualViewContainerState *_virtualViewContainerState;
123127
}
124128

@@ -640,6 +644,11 @@ - (void)_updateStateWithContentOffset
640644
return;
641645
}
642646

647+
BOOL enableImmediateUpdateModeForContentOffsetChanges =
648+
ReactNativeFeatureFlags::enableImmediateUpdateModeForContentOffsetChanges();
649+
650+
_avoidAdjustmentForMaintainVisibleContentPosition = enableImmediateUpdateModeForContentOffsetChanges;
651+
643652
auto contentOffset = RCTPointFromCGPoint(_scrollView.contentOffset);
644653
BOOL isAccessibilityAPIUsed = _isAccessibilityAPIUsed;
645654
_state->updateState(
@@ -655,9 +664,10 @@ - (void)_updateStateWithContentOffset
655664
UIAccessibilityIsVoiceOverRunning() || UIAccessibilityIsSwitchControlRunning() || isAccessibilityAPIUsed;
656665
return std::make_shared<const ScrollViewShadowNode::ConcreteState::Data>(newData);
657666
},
658-
ReactNativeFeatureFlags::enableImmediateUpdateModeForContentOffsetChanges()
659-
? EventQueue::UpdateMode::unstable_Immediate
660-
: EventQueue::UpdateMode::Asynchronous);
667+
enableImmediateUpdateModeForContentOffsetChanges ? EventQueue::UpdateMode::unstable_Immediate
668+
: EventQueue::UpdateMode::Asynchronous);
669+
670+
_avoidAdjustmentForMaintainVisibleContentPosition = NO;
661671
}
662672

663673
- (void)prepareForRecycle
@@ -1057,7 +1067,7 @@ - (void)_prepareForMaintainVisibleScrollPosition
10571067
- (void)_adjustForMaintainVisibleContentPosition
10581068
{
10591069
const auto &props = static_cast<const ScrollViewProps &>(*_props);
1060-
if (!props.maintainVisibleContentPosition) {
1070+
if (!props.maintainVisibleContentPosition || _avoidAdjustmentForMaintainVisibleContentPosition) {
10611071
return;
10621072
}
10631073

0 commit comments

Comments
 (0)