diff --git a/packages/react-native/React/Fabric/Mounting/ComponentViews/ScrollView/RCTScrollViewComponentView.mm b/packages/react-native/React/Fabric/Mounting/ComponentViews/ScrollView/RCTScrollViewComponentView.mm index 2802e65c6586..54a14a0b864a 100644 --- a/packages/react-native/React/Fabric/Mounting/ComponentViews/ScrollView/RCTScrollViewComponentView.mm +++ b/packages/react-native/React/Fabric/Mounting/ComponentViews/ScrollView/RCTScrollViewComponentView.mm @@ -360,9 +360,7 @@ - (void)updateProps:(const Props::Shared &)props oldProps:(const Props::Shared & MAP_SCROLL_VIEW_PROP(showsHorizontalScrollIndicator); MAP_SCROLL_VIEW_PROP(showsVerticalScrollIndicator); - if (oldScrollViewProps.automaticallyAdjustKeyboardInsets != newScrollViewProps.automaticallyAdjustKeyboardInsets) { - _automaticallyAdjustKeyboardInsets = newScrollViewProps.automaticallyAdjustKeyboardInsets; - } + _automaticallyAdjustKeyboardInsets = newScrollViewProps.automaticallyAdjustKeyboardInsets; if (oldScrollViewProps.scrollIndicatorInsets != newScrollViewProps.scrollIndicatorInsets) { _scrollView.scrollIndicatorInsets = RCTUIEdgeInsetsFromEdgeInsets(newScrollViewProps.scrollIndicatorInsets); @@ -702,6 +700,7 @@ - (void)prepareForRecycle // and keeps it as an opt-in behavior. _scrollView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever; _shouldUpdateContentInsetAdjustmentBehavior = YES; + _automaticallyAdjustKeyboardInsets = NO; _isUserTriggeredScrolling = NO; CGRect oldFrame = self.frame; self.frame = CGRectZero; diff --git a/packages/react-native/React/Tests/Mounting/RCTScrollViewComponentViewTests.mm b/packages/react-native/React/Tests/Mounting/RCTScrollViewComponentViewTests.mm new file mode 100644 index 000000000000..b8b6b78105fc --- /dev/null +++ b/packages/react-native/React/Tests/Mounting/RCTScrollViewComponentViewTests.mm @@ -0,0 +1,63 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#import +#import +#import +#import + +using namespace facebook::react; + +#if TARGET_OS_IOS + +static Props::Shared makeScrollViewProps(bool automaticallyAdjustKeyboardInsets) +{ + auto props = std::make_shared(); + props->automaticallyAdjustKeyboardInsets = automaticallyAdjustKeyboardInsets; + return props; +} + +@interface RCTScrollViewComponentView (Tests) +- (void)_keyboardWillChangeFrame:(NSNotification *)notification; +@end + +@interface RCTScrollViewComponentViewTests : XCTestCase +@end + +@implementation RCTScrollViewComponentViewTests + +- (void)testAutomaticallyAdjustKeyboardInsetsAcrossRecycling +{ + RCTScrollViewComponentView *view = [[RCTScrollViewComponentView alloc] initWithFrame:CGRectMake(0, 0, 100, 100)]; + auto props = makeScrollViewProps(true); + [view updateProps:props oldProps:ScrollViewShadowNode::defaultSharedProps()]; + + NSNotification *notification = [NSNotification + notificationWithName:UIKeyboardWillChangeFrameNotification + object:nil + userInfo:@{ + UIKeyboardAnimationDurationUserInfoKey : @0, + UIKeyboardAnimationCurveUserInfoKey : @(UIViewAnimationCurveLinear), + UIKeyboardFrameBeginUserInfoKey : [NSValue valueWithCGRect:CGRectMake(0, 100, 100, 50)], + UIKeyboardFrameEndUserInfoKey : [NSValue valueWithCGRect:CGRectMake(0, 50, 100, 50)], + }]; + + [view _keyboardWillChangeFrame:notification]; + XCTAssertEqual(view.scrollView.contentInset.bottom, 50); + + [view prepareForRecycle]; + [view _keyboardWillChangeFrame:notification]; + XCTAssertTrue(UIEdgeInsetsEqualToEdgeInsets(view.scrollView.contentInset, UIEdgeInsetsZero)); + + [view updateProps:props oldProps:nullptr]; + [view _keyboardWillChangeFrame:notification]; + XCTAssertEqual(view.scrollView.contentInset.bottom, 50); +} + +@end + +#endif