diff --git a/packages/react-native/Libraries/Components/ScrollView/ScrollView.js b/packages/react-native/Libraries/Components/ScrollView/ScrollView.js index a0221bd821c..63370df901a 100644 --- a/packages/react-native/Libraries/Components/ScrollView/ScrollView.js +++ b/packages/react-native/Libraries/Components/ScrollView/ScrollView.js @@ -392,7 +392,9 @@ export type ScrollViewPropsIOS = Readonly<{ * scrolls under the system UI. Across it, every value except `'never'` pads * the content container by the insets, so content is laid out clear of the * system UI, such as the rail on iPhone Duo or camera cutout in landscape, - * while the container's background still extends edge to edge. + * while the container's background still extends edge to edge. On every + * edge, the `contentContainerStyle` padding counts toward the inset, so + * content sits at the larger of the two. * * @default `'never'` * @platform ios diff --git a/packages/react-native/React/Fabric/Mounting/ComponentViews/ScrollView/RCTScrollContentViewComponentView.h b/packages/react-native/React/Fabric/Mounting/ComponentViews/ScrollView/RCTScrollContentViewComponentView.h index 2d539ab2ca2..1d418aa1afc 100644 --- a/packages/react-native/React/Fabric/Mounting/ComponentViews/ScrollView/RCTScrollContentViewComponentView.h +++ b/packages/react-native/React/Fabric/Mounting/ComponentViews/ScrollView/RCTScrollContentViewComponentView.h @@ -17,11 +17,19 @@ NS_ASSUME_NONNULL_BEGIN @interface RCTScrollContentViewComponentView : RCTViewComponentView /* - * The safe area the content is laid out clear of, as padding on top of the content container's own. The enclosing + * The safe area the content is laid out clear of, as a floor on the content container's own padding. The enclosing * scroll view sets the pair of insets across its scrollable axis, and zero while its `contentInsetAdjustmentBehavior` * is `never`. */ -@property (nonatomic, assign) UIEdgeInsets safeAreaPadding; +@property (nonatomic, readonly) UIEdgeInsets safeAreaPadding; + +/* + * The content inset UIKit adds for the safe area along the scrollable axis, which the content container's own padding + * on those edges counts toward. The enclosing scroll view sets the pair of insets along its scrollable axis. + */ +@property (nonatomic, readonly) UIEdgeInsets contentInsetAdjustment; + +- (void)setSafeAreaPadding:(UIEdgeInsets)safeAreaPadding contentInsetAdjustment:(UIEdgeInsets)contentInsetAdjustment; @end diff --git a/packages/react-native/React/Fabric/Mounting/ComponentViews/ScrollView/RCTScrollContentViewComponentView.mm b/packages/react-native/React/Fabric/Mounting/ComponentViews/ScrollView/RCTScrollContentViewComponentView.mm index 018d3c4ef00..80c8a598551 100644 --- a/packages/react-native/React/Fabric/Mounting/ComponentViews/ScrollView/RCTScrollContentViewComponentView.mm +++ b/packages/react-native/React/Fabric/Mounting/ComponentViews/ScrollView/RCTScrollContentViewComponentView.mm @@ -30,27 +30,32 @@ - (instancetype)initWithFrame:(CGRect)frame return self; } -- (void)setSafeAreaPadding:(UIEdgeInsets)safeAreaPadding +- (void)setSafeAreaPadding:(UIEdgeInsets)safeAreaPadding contentInsetAdjustment:(UIEdgeInsets)contentInsetAdjustment { _safeAreaPadding = safeAreaPadding; + _contentInsetAdjustment = contentInsetAdjustment; [self _updateStateIfNecessary]; } +static EdgeInsets RCTRoundedEdgeInsets(UIEdgeInsets insets) +{ + return { + .left = RCTRoundPixelValue(insets.left), + .top = RCTRoundPixelValue(insets.top), + .right = RCTRoundPixelValue(insets.right), + .bottom = RCTRoundPixelValue(insets.bottom)}; +} + - (void)_updateStateIfNecessary { if (!_state) { return; } - UIEdgeInsets insets = _safeAreaPadding; - insets.left = RCTRoundPixelValue(insets.left); - insets.top = RCTRoundPixelValue(insets.top); - insets.right = RCTRoundPixelValue(insets.right); - insets.bottom = RCTRoundPixelValue(insets.bottom); - RCTI18nUtil *i18nUtil = [RCTI18nUtil sharedInstance]; ScrollContentViewState newData; - newData.safeAreaPadding = RCTEdgeInsetsFromUIEdgeInsets(insets); + newData.safeAreaPadding = RCTRoundedEdgeInsets(_safeAreaPadding); + newData.contentInsetAdjustment = RCTRoundedEdgeInsets(_contentInsetAdjustment); newData.swapLeftAndRightInRTL = i18nUtil.isRTL && i18nUtil.doLeftAndRightSwapInRTL; if (newData == _lastStateData) { return; @@ -90,6 +95,7 @@ - (void)prepareForRecycle _state.reset(); _lastStateData = {}; _safeAreaPadding = UIEdgeInsetsZero; + _contentInsetAdjustment = UIEdgeInsetsZero; } @end 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 7550f08ae1a..39def82fb6d 100644 --- a/packages/react-native/React/Fabric/Mounting/ComponentViews/ScrollView/RCTScrollViewComponentView.mm +++ b/packages/react-native/React/Fabric/Mounting/ComponentViews/ScrollView/RCTScrollViewComponentView.mm @@ -888,10 +888,16 @@ - (void)layoutSubviews [self _updateContentViewSafeAreaPadding]; } +- (void)scrollViewDidChangeAdjustedContentInset:(UIScrollView *)scrollView +{ + [self _updateContentViewSafeAreaPadding]; +} + /* - * Hands the content container the safe area to pad its content by: the pair of insets across the scrollable axis, - * unless `contentInsetAdjustmentBehavior` is `never`. Along the scrollable axis UIKit turns the safe area into content - * insets instead, so content scrolls under the system UI. + * Hands the content container the safe area to lay its content out clear of, unless `contentInsetAdjustmentBehavior` + * is `never`: the pair of insets across the scrollable axis, which it pads by, and along the axis the content inset + * UIKit adds for the safe area, which its own padding counts toward. Content still scrolls under the system UI along + * the axis. */ - (void)_updateContentViewSafeAreaPadding { @@ -900,17 +906,24 @@ - (void)_updateContentViewSafeAreaPadding } const auto &props = static_cast(*_props); UIEdgeInsets padding = UIEdgeInsetsZero; + UIEdgeInsets contentInset = UIEdgeInsetsZero; if (props.contentInsetAdjustmentBehavior != ContentInsetAdjustmentBehavior::Never) { UIEdgeInsets insets = self.safeAreaInsets; + UIEdgeInsets adjusted = _scrollView.adjustedContentInset; + UIEdgeInsets current = _scrollView.contentInset; if (props.horizontal) { padding.top = insets.top; padding.bottom = insets.bottom; + contentInset.left = adjusted.left - current.left; + contentInset.right = adjusted.right - current.right; } else { padding.left = insets.left; padding.right = insets.right; + contentInset.top = adjusted.top - current.top; + contentInset.bottom = adjusted.bottom - current.bottom; } } - ((RCTScrollContentViewComponentView *)_contentView).safeAreaPadding = padding; + [(RCTScrollContentViewComponentView *)_contentView setSafeAreaPadding:padding contentInsetAdjustment:contentInset]; } - (void)_handleScrollEndIfNeeded diff --git a/packages/react-native/ReactCommon/react/renderer/components/scrollview/ScrollContentViewShadowNode.cpp b/packages/react-native/ReactCommon/react/renderer/components/scrollview/ScrollContentViewShadowNode.cpp index 0632d156cb9..67d97db8cf1 100644 --- a/packages/react-native/ReactCommon/react/renderer/components/scrollview/ScrollContentViewShadowNode.cpp +++ b/packages/react-native/ReactCommon/react/renderer/components/scrollview/ScrollContentViewShadowNode.cpp @@ -7,6 +7,7 @@ #include "ScrollContentViewShadowNode.h" +#include #include namespace facebook::react { @@ -78,16 +79,21 @@ StyleLength resolvedPadding( } /* + * The safe area is a floor on the padding, as it is on UIKit's layout + * margins: the edge takes the larger of its style padding and the inset. + * Where UIKit already applies the inset as a content inset, the edge keeps + * what its padding exceeds that by, which lands the content on the same floor. * A percentage padding keeps the edge as the style set it, with no inset - * added, since Yoga holds one length per edge and a percentage has no point - * value to add to. + * applied, since Yoga holds one length per edge and a percentage has no point + * value to compare. */ -StyleLength padded(StyleLength value, Float inset) { - if (inset == 0 || value.isPercent()) { +StyleLength padded(StyleLength value, Float inset, Float contentInset) { + if ((inset == 0 && contentInset == 0) || value.isPercent()) { return value; } - auto base = value.isPoints() ? value.value().unwrap() : 0.0f; - return StyleLength::points(base + inset); + auto base = value.isPoints() ? Float{value.value().unwrap()} : Float{0}; + return StyleLength::points( + std::max(std::max(base, inset) - contentInset, Float{0})); } } // namespace @@ -131,22 +137,31 @@ void ScrollContentViewShadowNode::applySafeAreaPadding() { const ScrollContentViewState& state, LayoutDirection layoutDirection) { const auto& insets = state.safeAreaPadding; + const auto& contentInsets = state.contentInsetAdjustment; auto swap = state.swapLeftAndRightInRTL; - if (insets.top != 0 || insets.bottom != 0) { + if (insets.top != 0 || insets.bottom != 0 || contentInsets.top != 0 || + contentInsets.bottom != 0) { auto top = padded( - resolvedPadding(style, Edge::Top, layoutDirection, swap), insets.top); + resolvedPadding(style, Edge::Top, layoutDirection, swap), + insets.top, + contentInsets.top); auto bottom = padded( resolvedPadding(style, Edge::Bottom, layoutDirection, swap), - insets.bottom); + insets.bottom, + contentInsets.bottom); style.setPadding(Edge::Top, top); style.setPadding(Edge::Bottom, bottom); } - if (insets.left != 0 || insets.right != 0) { + if (insets.left != 0 || insets.right != 0 || contentInsets.left != 0 || + contentInsets.right != 0) { auto left = padded( - resolvedPadding(style, Edge::Left, layoutDirection, swap), insets.left); + resolvedPadding(style, Edge::Left, layoutDirection, swap), + insets.left, + contentInsets.left); auto right = padded( resolvedPadding(style, Edge::Right, layoutDirection, swap), - insets.right); + insets.right, + contentInsets.right); // The logical edges take precedence over every other padding edge along // the row. The physical edges are cleared, since at layout they are copied // over the logical ones when left and right swap in RTL. diff --git a/packages/react-native/ReactCommon/react/renderer/components/scrollview/ScrollContentViewShadowNode.h b/packages/react-native/ReactCommon/react/renderer/components/scrollview/ScrollContentViewShadowNode.h index 5096b8bfecc..8535f3e9f56 100644 --- a/packages/react-native/ReactCommon/react/renderer/components/scrollview/ScrollContentViewShadowNode.h +++ b/packages/react-native/ReactCommon/react/renderer/components/scrollview/ScrollContentViewShadowNode.h @@ -21,8 +21,9 @@ extern const char ScrollContentViewComponentName[]; /* * `ShadowNode` for the component, the content container of - * a . It pads its content by the safe area in its state, on top of - * the padding its style sets. + * a . It lays its content out clear of the safe area in its state + * by at least the padding its style sets: across the scrollable axis as + * padding, and along it as what the padding exceeds UIKit's content inset by. */ class ScrollContentViewShadowNode final : public ConcreteViewShadowNode< ScrollContentViewComponentName, @@ -46,10 +47,11 @@ class ScrollContentViewShadowNode final : public ConcreteViewShadowNode< void applySafeAreaPadding(); /* - * Pads `style` by `state.safeAreaPadding`, on top of the padding `style` - * resolves to on each edge, following the precedence Yoga gives the padding - * edges for `layoutDirection`. An edge with a percentage padding keeps it - * and gets no inset. + * Raises the padding `style` resolves to on each edge to at least + * `state.safeAreaPadding`, less `state.contentInsetAdjustment` where UIKit + * already applies the safe area as a content inset, following the precedence + * Yoga gives the padding edges for `layoutDirection`. An edge with a + * percentage padding keeps it and gets no inset. */ static void padForSafeArea(yoga::Style &style, const ScrollContentViewState &state, LayoutDirection layoutDirection); diff --git a/packages/react-native/ReactCommon/react/renderer/components/scrollview/ScrollContentViewState.h b/packages/react-native/ReactCommon/react/renderer/components/scrollview/ScrollContentViewState.h index d1398350d91..b067d81333e 100644 --- a/packages/react-native/ReactCommon/react/renderer/components/scrollview/ScrollContentViewState.h +++ b/packages/react-native/ReactCommon/react/renderer/components/scrollview/ScrollContentViewState.h @@ -25,12 +25,19 @@ namespace facebook::react { class ScrollContentViewState final { public: /* - * The safe area the content is laid out clear of, as padding on top of the - * padding the style sets. The enclosing scroll view sets the pair of edges - * across its scrollable axis. + * The safe area the content is laid out clear of, as a floor on the padding + * the style sets. The enclosing scroll view sets the pair of edges across + * its scrollable axis. */ EdgeInsets safeAreaPadding{}; + /* + * The content inset UIKit adds for the safe area along the scrollable axis, + * which the padding the style sets on those edges counts toward. The + * enclosing scroll view sets the pair of edges along its scrollable axis. + */ + EdgeInsets contentInsetAdjustment{}; + /* * Whether left and right swap in RTL, which decides the padding edges the * safe area adds to. @@ -48,6 +55,11 @@ class ScrollContentViewState final { (Float)data["top"].getDouble(), (Float)data["right"].getDouble(), (Float)data["bottom"].getDouble()}), + contentInsetAdjustment( + {(Float)data["contentInsetLeft"].getDouble(), + (Float)data["contentInsetTop"].getDouble(), + (Float)data["contentInsetRight"].getDouble(), + (Float)data["contentInsetBottom"].getDouble()}), swapLeftAndRightInRTL(data["swapLeftAndRightInRTL"].getBool()) { } @@ -56,6 +68,8 @@ class ScrollContentViewState final { { return folly::dynamic::object("left", safeAreaPadding.left)("top", safeAreaPadding.top)( "right", safeAreaPadding.right)("bottom", safeAreaPadding.bottom)( + "contentInsetLeft", contentInsetAdjustment.left)("contentInsetTop", contentInsetAdjustment.top)( + "contentInsetRight", contentInsetAdjustment.right)("contentInsetBottom", contentInsetAdjustment.bottom)( "swapLeftAndRightInRTL", swapLeftAndRightInRTL); } #endif diff --git a/packages/react-native/ReactCommon/react/renderer/components/scrollview/tests/ScrollContentViewTest.cpp b/packages/react-native/ReactCommon/react/renderer/components/scrollview/tests/ScrollContentViewTest.cpp index ed0c689b7b4..c830bb6efc6 100644 --- a/packages/react-native/ReactCommon/react/renderer/components/scrollview/tests/ScrollContentViewTest.cpp +++ b/packages/react-native/ReactCommon/react/renderer/components/scrollview/tests/ScrollContentViewTest.cpp @@ -32,6 +32,13 @@ ScrollContentViewState stateWith( return state; } +ScrollContentViewState stateWithContentInset( + EdgeInsets contentInsetAdjustment) { + ScrollContentViewState state; + state.contentInsetAdjustment = contentInsetAdjustment; + return state; +} + constexpr auto kLTR = LayoutDirection::LeftToRight; constexpr auto kRTL = LayoutDirection::RightToLeft; @@ -47,7 +54,7 @@ TEST(ScrollContentViewShadowNodeTest, leavesStyleWithoutInsets) { EXPECT_FALSE(style.padding(Edge::Start).isDefined()); } -TEST(ScrollContentViewShadowNodeTest, padsRowOnTopOfResolvedPadding) { +TEST(ScrollContentViewShadowNodeTest, raisesRowPaddingToTheInset) { yoga::Style style; style.setPadding(Edge::Horizontal, StyleLength::points(16)); @@ -55,20 +62,31 @@ TEST(ScrollContentViewShadowNodeTest, padsRowOnTopOfResolvedPadding) { style, stateWith({.left = 0, .top = 0, .right = 84, .bottom = 0}), kLTR); EXPECT_EQ(style.padding(Edge::Start), StyleLength::points(16)); - EXPECT_EQ(style.padding(Edge::End), StyleLength::points(100)); + EXPECT_EQ(style.padding(Edge::End), StyleLength::points(84)); EXPECT_FALSE(style.padding(Edge::Left).isDefined()); EXPECT_FALSE(style.padding(Edge::Right).isDefined()); } +TEST(ScrollContentViewShadowNodeTest, keepsPaddingLargerThanTheInset) { + yoga::Style style; + style.setPadding(Edge::Horizontal, StyleLength::points(100)); + + ScrollContentViewShadowNode::padForSafeArea( + style, stateWith({.left = 0, .top = 0, .right = 84, .bottom = 0}), kLTR); + + EXPECT_EQ(style.padding(Edge::Start), StyleLength::points(100)); + EXPECT_EQ(style.padding(Edge::End), StyleLength::points(100)); +} + TEST(ScrollContentViewShadowNodeTest, prefersLogicalOverPhysicalEdge) { yoga::Style style; style.setPadding(Edge::Left, StyleLength::points(4)); - style.setPadding(Edge::Start, StyleLength::points(12)); + style.setPadding(Edge::Start, StyleLength::points(40)); ScrollContentViewShadowNode::padForSafeArea( style, stateWith({.left = 20, .top = 0, .right = 0, .bottom = 0}), kLTR); - EXPECT_EQ(style.padding(Edge::Start), StyleLength::points(32)); + EXPECT_EQ(style.padding(Edge::Start), StyleLength::points(40)); } TEST(ScrollContentViewShadowNodeTest, keepsPercentageAndSkipsInsetOnThatEdge) { @@ -92,7 +110,7 @@ TEST(ScrollContentViewShadowNodeTest, padsPointsEdgeBesideAPercentageEdge) { style, stateWith({.left = 20, .top = 0, .right = 84, .bottom = 0}), kLTR); EXPECT_EQ(style.padding(Edge::Start), StyleLength::percent(10)); - EXPECT_EQ(style.padding(Edge::End), StyleLength::points(88)); + EXPECT_EQ(style.padding(Edge::End), StyleLength::points(84)); } TEST(ScrollContentViewShadowNodeTest, padsPhysicalEdgesInRTL) { @@ -103,7 +121,7 @@ TEST(ScrollContentViewShadowNodeTest, padsPhysicalEdgesInRTL) { style, stateWith({.left = 0, .top = 0, .right = 84, .bottom = 0}), kRTL); // In RTL the start edge is on the right, where the inset is. - EXPECT_EQ(style.padding(Edge::Start), StyleLength::points(96)); + EXPECT_EQ(style.padding(Edge::Start), StyleLength::points(84)); EXPECT_FALSE(style.padding(Edge::End).isDefined()); } @@ -118,15 +136,15 @@ TEST(ScrollContentViewShadowNodeTest, readsSwappedPhysicalEdgesInRTL) { kRTL); // Left is copied over start at layout, so it lands on the right, and the - // inset on the left adds to the end edge. + // inset on the left raises the end edge. EXPECT_EQ(style.padding(Edge::Start), StyleLength::points(8)); - EXPECT_EQ(style.padding(Edge::End), StyleLength::points(86)); + EXPECT_EQ(style.padding(Edge::End), StyleLength::points(84)); EXPECT_FALSE(style.padding(Edge::Left).isDefined()); } TEST(ScrollContentViewShadowNodeTest, readsSwappedPhysicalEdgesInLTRSubtree) { yoga::Style style; - style.setPadding(Edge::Left, StyleLength::points(8)); + style.setPadding(Edge::Left, StyleLength::points(100)); style.setPadding(Edge::Start, StyleLength::points(2)); ScrollContentViewShadowNode::padForSafeArea( @@ -136,7 +154,7 @@ TEST(ScrollContentViewShadowNodeTest, readsSwappedPhysicalEdgesInLTRSubtree) { // The swap applies to the whole tree, so left is still copied over start, // which a node laid out left to right keeps on the left. - EXPECT_EQ(style.padding(Edge::Start), StyleLength::points(92)); + EXPECT_EQ(style.padding(Edge::Start), StyleLength::points(100)); EXPECT_FALSE(style.padding(Edge::End).isDefined()); } @@ -147,11 +165,66 @@ TEST(ScrollContentViewShadowNodeTest, padsColumnForHorizontalScrollView) { ScrollContentViewShadowNode::padForSafeArea( style, stateWith({.left = 0, .top = 20, .right = 0, .bottom = 34}), kLTR); - EXPECT_EQ(style.padding(Edge::Top), StyleLength::points(24)); - EXPECT_EQ(style.padding(Edge::Bottom), StyleLength::points(38)); + EXPECT_EQ(style.padding(Edge::Top), StyleLength::points(20)); + EXPECT_EQ(style.padding(Edge::Bottom), StyleLength::points(34)); EXPECT_EQ(style.padding(Edge::Vertical), StyleLength::points(4)); } +TEST(ScrollContentViewShadowNodeTest, reducesColumnPaddingByTheContentInset) { + yoga::Style style; + style.setPadding(Edge::Vertical, StyleLength::points(20)); + + ScrollContentViewShadowNode::padForSafeArea( + style, + stateWithContentInset({.left = 0, .top = 59, .right = 0, .bottom = 34}), + kLTR); + + // UIKit's content inset already keeps the content clear of the safe area + // along the scrollable axis, so a smaller padding sits inside it. + EXPECT_EQ(style.padding(Edge::Top), StyleLength::points(0)); + EXPECT_EQ(style.padding(Edge::Bottom), StyleLength::points(0)); +} + +TEST(ScrollContentViewShadowNodeTest, keepsColumnPaddingBeyondTheContentInset) { + yoga::Style style; + style.setPadding(Edge::Vertical, StyleLength::points(100)); + + ScrollContentViewShadowNode::padForSafeArea( + style, + stateWithContentInset({.left = 0, .top = 59, .right = 0, .bottom = 34}), + kLTR); + + EXPECT_EQ(style.padding(Edge::Top), StyleLength::points(41)); + EXPECT_EQ(style.padding(Edge::Bottom), StyleLength::points(66)); +} + +TEST(ScrollContentViewShadowNodeTest, reducesRowPaddingByTheContentInsetInRTL) { + yoga::Style style; + style.setPadding(Edge::Horizontal, StyleLength::points(100)); + + ScrollContentViewShadowNode::padForSafeArea( + style, + stateWithContentInset({.left = 59, .top = 0, .right = 0, .bottom = 0}), + kRTL); + + // In RTL the end edge is on the left, where the content inset is. + EXPECT_EQ(style.padding(Edge::Start), StyleLength::points(100)); + EXPECT_EQ(style.padding(Edge::End), StyleLength::points(41)); +} + +TEST(ScrollContentViewShadowNodeTest, keepsPercentageBesideTheContentInset) { + yoga::Style style; + style.setPadding(Edge::Vertical, StyleLength::percent(10)); + + ScrollContentViewShadowNode::padForSafeArea( + style, + stateWithContentInset({.left = 0, .top = 59, .right = 0, .bottom = 0}), + kLTR); + + EXPECT_EQ(style.padding(Edge::Top), StyleLength::percent(10)); + EXPECT_EQ(style.padding(Edge::Bottom), StyleLength::percent(10)); +} + TEST(ScrollContentViewShadowNodeTest, cloningForChildCommitMustNotDirty) { ComponentDescriptorProviderRegistry providerRegistry{}; auto registry = providerRegistry.createComponentDescriptorRegistry( diff --git a/packages/rn-tester/js/examples/ScrollView/ScrollViewExample.js b/packages/rn-tester/js/examples/ScrollView/ScrollViewExample.js index 71d12f82c5c..1e6008cb5b8 100644 --- a/packages/rn-tester/js/examples/ScrollView/ScrollViewExample.js +++ b/packages/rn-tester/js/examples/ScrollView/ScrollViewExample.js @@ -360,7 +360,7 @@ const examples: Array = [ { title: ' Content Inset Adjustment Behavior\n', description: - 'How the safe area modifies the content area of a full screen ScrollView: along the scrollable axis it becomes content insets, across it the content container is padded.', + 'How the safe area modifies the content area of a full screen ScrollView: along the scrollable axis it becomes content insets, across it the content container is padded, and on every edge the container padding counts toward it.', platform: 'ios', render(): React.Node { return ; @@ -1832,6 +1832,7 @@ const styles = StyleSheet.create({ }, fullScreenContentContainer: { backgroundColor: '#aae3b6', + padding: 20, }, fullScreenControls: { backgroundColor: '#eeeeee', diff --git a/scripts/cxx-api/api-snapshots/ReactAppleDebugCxx.api b/scripts/cxx-api/api-snapshots/ReactAppleDebugCxx.api index 77cba39953d..9149ec64fa1 100644 --- a/scripts/cxx-api/api-snapshots/ReactAppleDebugCxx.api +++ b/scripts/cxx-api/api-snapshots/ReactAppleDebugCxx.api @@ -1596,7 +1596,9 @@ interface RCTScheduler : public NSObject { } interface RCTScrollContentViewComponentView : public RCTViewComponentView { - public @property (assign) UIEdgeInsets safeAreaPadding; + public @property (assign, readonly) UIEdgeInsets contentInsetAdjustment; + public @property (assign, readonly) UIEdgeInsets safeAreaPadding; + public virtual void setSafeAreaPadding:contentInsetAdjustment:(UIEdgeInsets safeAreaPadding, UIEdgeInsets contentInsetAdjustment); } interface RCTScrollEvent : public NSObject { diff --git a/scripts/cxx-api/api-snapshots/ReactAppleFrameworksCxx.api b/scripts/cxx-api/api-snapshots/ReactAppleFrameworksCxx.api index bc82eb79990..6a83f13c3a6 100644 --- a/scripts/cxx-api/api-snapshots/ReactAppleFrameworksCxx.api +++ b/scripts/cxx-api/api-snapshots/ReactAppleFrameworksCxx.api @@ -1639,7 +1639,9 @@ interface RCTScheduler : public NSObject { } interface RCTScrollContentViewComponentView : public RCTViewComponentView { - public @property (assign) UIEdgeInsets safeAreaPadding; + public @property (assign, readonly) UIEdgeInsets contentInsetAdjustment; + public @property (assign, readonly) UIEdgeInsets safeAreaPadding; + public virtual void setSafeAreaPadding:contentInsetAdjustment:(UIEdgeInsets safeAreaPadding, UIEdgeInsets contentInsetAdjustment); } interface RCTScrollEvent : public NSObject { diff --git a/scripts/cxx-api/api-snapshots/ReactAppleNewarchCxx.api b/scripts/cxx-api/api-snapshots/ReactAppleNewarchCxx.api index 8d6e1d36c9b..339ee5275c0 100644 --- a/scripts/cxx-api/api-snapshots/ReactAppleNewarchCxx.api +++ b/scripts/cxx-api/api-snapshots/ReactAppleNewarchCxx.api @@ -1595,7 +1595,9 @@ interface RCTScheduler : public NSObject { } interface RCTScrollContentViewComponentView : public RCTViewComponentView { - public @property (assign) UIEdgeInsets safeAreaPadding; + public @property (assign, readonly) UIEdgeInsets contentInsetAdjustment; + public @property (assign, readonly) UIEdgeInsets safeAreaPadding; + public virtual void setSafeAreaPadding:contentInsetAdjustment:(UIEdgeInsets safeAreaPadding, UIEdgeInsets contentInsetAdjustment); } interface RCTScrollEvent : public NSObject { diff --git a/scripts/cxx-api/api-snapshots/ReactAppleReleaseCxx.api b/scripts/cxx-api/api-snapshots/ReactAppleReleaseCxx.api index ce64ee06024..a9a525bb8ce 100644 --- a/scripts/cxx-api/api-snapshots/ReactAppleReleaseCxx.api +++ b/scripts/cxx-api/api-snapshots/ReactAppleReleaseCxx.api @@ -1596,7 +1596,9 @@ interface RCTScheduler : public NSObject { } interface RCTScrollContentViewComponentView : public RCTViewComponentView { - public @property (assign) UIEdgeInsets safeAreaPadding; + public @property (assign, readonly) UIEdgeInsets contentInsetAdjustment; + public @property (assign, readonly) UIEdgeInsets safeAreaPadding; + public virtual void setSafeAreaPadding:contentInsetAdjustment:(UIEdgeInsets safeAreaPadding, UIEdgeInsets contentInsetAdjustment); } interface RCTScrollEvent : public NSObject {