Skip to content

Commit 28a65f4

Browse files
Dmitry Rykunfacebook-github-bot
Dmitry Rykun
authored andcommitted
ScrollView fails when contentInsetAdjustmentBehavior is automatic
Summary: Fix to reactwg/react-native-new-architecture#30 We have already applied this solution to both [pre-Fabric](https://www.internalfb.com/code/fbsource/[1da0f2e3164d6f87e8221e0f0462ae93fdc5cbdc]/xplat/js/react-native-github/React/Views/ScrollView/RCTScrollView.m?lines=361) and [Fabric](https://www.internalfb.com/code/fbsource/[1da0f2e3164d6f87e8221e0f0462ae93fdc5cbdc]/xplat/js/react-native-github/React/Fabric/Mounting/ComponentViews/ScrollView/RCTEnhancedScrollView.mm?lines=36) scroll views. However Fabric can reuse components, and this has to be reapplied at every reuse. Changelog [iOS][Fixed] - ScrollView's contentInsetAdjustmentBehavior is reset to Never at every reuse to avoid layout artifacts. Reviewed By: cipolleschi Differential Revision: D35965080 fbshipit-source-id: 3ac26cf304b608d09ae6c0f05588b664381551f2
1 parent dfc24fa commit 28a65f4

File tree

1 file changed

+10
-1
lines changed

1 file changed

+10
-1
lines changed

React/Fabric/Mounting/ComponentViews/ScrollView/RCTScrollViewComponentView.mm

+10-1
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ @implementation RCTScrollViewComponentView {
9797
// This helps to only update state from `scrollViewDidScroll` in case
9898
// some other part of the system scrolls scroll view.
9999
BOOL _isUserTriggeredScrolling;
100+
BOOL _shouldUpdateContentInsetAdjustmentBehavior;
100101

101102
CGPoint _contentOffsetWhenClipped;
102103
}
@@ -120,6 +121,7 @@ - (instancetype)initWithFrame:(CGRect)frame
120121
_scrollView.delaysContentTouches = NO;
121122
((RCTEnhancedScrollView *)_scrollView).overridingDelegate = self;
122123
_isUserTriggeredScrolling = NO;
124+
_shouldUpdateContentInsetAdjustmentBehavior = YES;
123125
[self addSubview:_scrollView];
124126

125127
_containerView = [[UIView alloc] initWithFrame:CGRectZero];
@@ -266,7 +268,8 @@ - (void)updateProps:(Props::Shared const &)props oldProps:(Props::Shared const &
266268
}
267269
}
268270

269-
if (oldScrollViewProps.contentInsetAdjustmentBehavior != newScrollViewProps.contentInsetAdjustmentBehavior) {
271+
if ((oldScrollViewProps.contentInsetAdjustmentBehavior != newScrollViewProps.contentInsetAdjustmentBehavior) ||
272+
_shouldUpdateContentInsetAdjustmentBehavior) {
270273
auto const contentInsetAdjustmentBehavior = newScrollViewProps.contentInsetAdjustmentBehavior;
271274
if (contentInsetAdjustmentBehavior == ContentInsetAdjustmentBehavior::Never) {
272275
scrollView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
@@ -277,6 +280,7 @@ - (void)updateProps:(Props::Shared const &)props oldProps:(Props::Shared const &
277280
} else if (contentInsetAdjustmentBehavior == ContentInsetAdjustmentBehavior::Always) {
278281
scrollView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentAlways;
279282
}
283+
_shouldUpdateContentInsetAdjustmentBehavior = NO;
280284
}
281285

282286
MAP_SCROLL_VIEW_PROP(disableIntervalMomentum);
@@ -390,6 +394,11 @@ - (void)prepareForRecycle
390394
{
391395
const auto &props = *std::static_pointer_cast<const ScrollViewProps>(_props);
392396
_scrollView.contentOffset = RCTCGPointFromPoint(props.contentOffset);
397+
// We set the default behavior to "never" so that iOS
398+
// doesn't do weird things to UIScrollView insets automatically
399+
// and keeps it as an opt-in behavior.
400+
_scrollView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
401+
_shouldUpdateContentInsetAdjustmentBehavior = YES;
393402
_state.reset();
394403
_isUserTriggeredScrolling = NO;
395404
[super prepareForRecycle];

0 commit comments

Comments
 (0)