diff --git a/packages/react-native/React/Fabric/Mounting/ComponentViews/ScrollView/RCTEnhancedScrollView.mm b/packages/react-native/React/Fabric/Mounting/ComponentViews/ScrollView/RCTEnhancedScrollView.mm index b3481c1b98b4..03c9ce7fadcf 100644 --- a/packages/react-native/React/Fabric/Mounting/ComponentViews/ScrollView/RCTEnhancedScrollView.mm +++ b/packages/react-native/React/Fabric/Mounting/ComponentViews/ScrollView/RCTEnhancedScrollView.mm @@ -31,10 +31,16 @@ + (BOOL)automaticallyNotifiesObserversForKey:(NSString *)key - (instancetype)initWithFrame:(CGRect)frame { if (self = [super initWithFrame:frame]) { - // We set the default behavior to "never" so that iOS - // doesn't do weird things to UIScrollView insets automatically - // and keeps it as an opt-in behavior. - self.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever; + if (@available(iOS 26, *)) { + NSNumber *compat = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"UIDesignRequiresCompatibility"]; + if (!compat.boolValue) { + self.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentScrollableAxes; + } else { + self.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever; + } + } else { + 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 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 548987ff291d..c8348cd539cc 100644 --- a/packages/react-native/React/Fabric/Mounting/ComponentViews/ScrollView/RCTScrollViewComponentView.mm +++ b/packages/react-native/React/Fabric/Mounting/ComponentViews/ScrollView/RCTScrollViewComponentView.mm @@ -436,7 +436,13 @@ - (void)updateProps:(const Props::Shared &)props oldProps:(const Props::Shared & if ((oldScrollViewProps.contentInsetAdjustmentBehavior != newScrollViewProps.contentInsetAdjustmentBehavior) || _shouldUpdateContentInsetAdjustmentBehavior) { - const auto contentInsetAdjustmentBehavior = newScrollViewProps.contentInsetAdjustmentBehavior; + auto contentInsetAdjustmentBehavior = newScrollViewProps.contentInsetAdjustmentBehavior; + if (@available(iOS 26, *)) { + NSNumber *compat = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"UIDesignRequiresCompatibility"]; + if (!compat.boolValue && contentInsetAdjustmentBehavior == ContentInsetAdjustmentBehavior::Never) { + contentInsetAdjustmentBehavior = ContentInsetAdjustmentBehavior::ScrollableAxes; + } + } if (contentInsetAdjustmentBehavior == ContentInsetAdjustmentBehavior::Never) { scrollView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever; } else if (contentInsetAdjustmentBehavior == ContentInsetAdjustmentBehavior::Automatic) { @@ -698,10 +704,16 @@ - (void)prepareForRecycle _contentSize = CGSizeZero; // Reset contentInset to prevent stale insets leaking into recycled scroll views. _scrollView.contentInset = UIEdgeInsetsZero; - // We set the default behavior to "never" so that iOS - // doesn't do weird things to UIScrollView insets automatically - // and keeps it as an opt-in behavior. - _scrollView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever; + if (@available(iOS 26, *)) { + NSNumber *compat = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"UIDesignRequiresCompatibility"]; + if (!compat.boolValue) { + _scrollView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentScrollableAxes; + } else { + _scrollView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever; + } + } else { + _scrollView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever; + } _shouldUpdateContentInsetAdjustmentBehavior = YES; _isUserTriggeredScrolling = NO; CGRect oldFrame = self.frame;