Skip to content

Commit 79a8354

Browse files
sammy-SCfacebook-github-bot
authored andcommitted
attempt to fix maintain visible content position prop with view culling (#53472)
Summary: Pull Request resolved: #53472 changelog: [internal] I am looking into stalls when View Culling is turned on together with immediate state updates. This is one of the places where stalls are concentrated and this seems like a possible culprit: When view is moved outside of the viewport, it is immediately reused. Therefore, we must check view's identity to make sure it is the same view before and after transaction. Reviewed By: lenaic Differential Revision: D81044328 fbshipit-source-id: 796b71219e5fc94c1f98319b73f4655b9c13000f
1 parent 37b61ac commit 79a8354

File tree

1 file changed

+11
-1
lines changed

1 file changed

+11
-1
lines changed

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

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,7 @@ @implementation RCTScrollViewComponentView {
111111

112112
CGRect _prevFirstVisibleFrame;
113113
__weak UIView *_firstVisibleView;
114+
NSInteger _firstVisibleViewTag;
114115

115116
CGFloat _endDraggingSensitivityMultiplier;
116117

@@ -691,6 +692,7 @@ - (void)prepareForRecycle
691692
_contentView = nil;
692693
_prevFirstVisibleFrame = CGRectZero;
693694
_firstVisibleView = nil;
695+
_firstVisibleViewTag = 0;
694696
_virtualViewContainerState = nil;
695697
}
696698

@@ -1041,7 +1043,7 @@ - (void)removeScrollListener:(NSObject<UIScrollViewDelegate> *)scrollListener
10411043
- (void)_prepareForMaintainVisibleScrollPosition
10421044
{
10431045
const auto &props = static_cast<const ScrollViewProps &>(*_props);
1044-
if (!props.maintainVisibleContentPosition) {
1046+
if (!props.maintainVisibleContentPosition || _avoidAdjustmentForMaintainVisibleContentPosition) {
10451047
return;
10461048
}
10471049

@@ -1059,6 +1061,7 @@ - (void)_prepareForMaintainVisibleScrollPosition
10591061
if (hasNewView || ii == _contentView.subviews.count - 1) {
10601062
_prevFirstVisibleFrame = subview.frame;
10611063
_firstVisibleView = subview;
1064+
_firstVisibleViewTag = subview.tag;
10621065
break;
10631066
}
10641067
}
@@ -1071,6 +1074,13 @@ - (void)_adjustForMaintainVisibleContentPosition
10711074
return;
10721075
}
10731076

1077+
if (ReactNativeFeatureFlags::enableViewCulling()) {
1078+
// Abort if the first visible view has changed (different tag)
1079+
if (_firstVisibleView && _firstVisibleView.tag != _firstVisibleViewTag) {
1080+
return;
1081+
}
1082+
}
1083+
10741084
std::optional<int> autoscrollThreshold = props.maintainVisibleContentPosition.value().autoscrollToTopThreshold;
10751085
BOOL horizontal = _scrollView.contentSize.width > self.frame.size.width;
10761086
// TODO: detect and handle/ignore re-ordering

0 commit comments

Comments
 (0)