Bug
contentInsetAdjustmentBehavior has no effect on UIScrollView instances (including FlashList / FlatList) embedded inside PagerView pages. Scroll views report safeAreaInsets = .zero, so they cannot automatically adjust content insets for overlapping system chrome (e.g. translucent tab bars on iOS 26 liquid glass).
Environment
- react-native-pager-view: 8.0.0
- React Native: 0.78
- iOS: 26 (liquid glass translucent tab bar with
drawBehind: true)
- Architecture: New Architecture (Fabric)
Steps to reproduce
- Use a bottom tab navigator with
drawBehind: true and a translucent tab bar (iOS 26 liquid glass)
- Place a
PagerView inside a tab screen
- Add a scrollable list (e.g.
FlashList or FlatList) inside a PagerView page
- Set
contentInsetAdjustmentBehavior='scrollableAxes' on the scroll view
- Scroll to the bottom of the list
Expected: Last item stops above the tab bar (scroll view adds ~83pt bottom content inset automatically)
Actual: Last items are hidden behind the tab bar. The scroll view's adjustedContentInset.bottom remains 0.
Root cause
The UIHostingController is initialized with ignoreSafeArea: true (PagerViewProvider.swift L109-111), which calls disableSafeArea() and dynamically subclasses the hosting view to override safeAreaInsets → .zero.
Even without ignoreSafeArea, RepresentableView uses UIViewRepresentable which embeds a plain wrapper UIView. SwiftUI does not propagate safe area insets through UIViewRepresentable — the wrapper and all its descendant UIKit views see safeAreaInsets = .zero.
Debug log evidence (added print statements to trace the view hierarchy):
HostingController.view.safeAreaInsets: bottom: 83 ← correct at hosting level
PagingCollectionView.safeAreaInsets: bottom: 83 ← correct at TabView collection
Wrapper UIView.safeAreaInsets: bottom: 0 ← LOST HERE (UIViewRepresentable boundary)
RCTEnhancedScrollView.safeAreaInsets: bottom: 0 ← zero → contentInsetAdjustmentBehavior noop
contentInsetAdjustmentBehavior: 2 (scrollableAxes)
adjustedContentInset: bottom: 0 ← no adjustment despite scrollableAxes
Proposed fix
PR #1085 addresses this with three changes:
- Replace
UIViewRepresentable → UIViewControllerRepresentable with a PageChildViewController that reads the hosting view's real safeAreaInsets and re-injects them via additionalSafeAreaInsets
- Add
.ignoresSafeArea() to the SwiftUI TabView body so pages extend behind system chrome
- Remove
ignoreSafeArea: true from UIHostingController init so the hosting view preserves real insets
Bug
contentInsetAdjustmentBehaviorhas no effect onUIScrollViewinstances (includingFlashList/FlatList) embedded inside PagerView pages. Scroll views reportsafeAreaInsets = .zero, so they cannot automatically adjust content insets for overlapping system chrome (e.g. translucent tab bars on iOS 26 liquid glass).Environment
drawBehind: true)Steps to reproduce
drawBehind: trueand a translucent tab bar (iOS 26 liquid glass)PagerViewinside a tab screenFlashListorFlatList) inside a PagerView pagecontentInsetAdjustmentBehavior='scrollableAxes'on the scroll viewExpected: Last item stops above the tab bar (scroll view adds ~83pt bottom content inset automatically)
Actual: Last items are hidden behind the tab bar. The scroll view's
adjustedContentInset.bottomremains 0.Root cause
The
UIHostingControlleris initialized withignoreSafeArea: true(PagerViewProvider.swiftL109-111), which callsdisableSafeArea()and dynamically subclasses the hosting view to overridesafeAreaInsets→.zero.Even without
ignoreSafeArea,RepresentableViewusesUIViewRepresentablewhich embeds a plain wrapperUIView. SwiftUI does not propagate safe area insets throughUIViewRepresentable— the wrapper and all its descendant UIKit views seesafeAreaInsets = .zero.Debug log evidence (added
printstatements to trace the view hierarchy):Proposed fix
PR #1085 addresses this with three changes:
UIViewRepresentable→UIViewControllerRepresentablewith aPageChildViewControllerthat reads the hosting view's realsafeAreaInsetsand re-injects them viaadditionalSafeAreaInsets.ignoresSafeArea()to the SwiftUITabViewbody so pages extend behind system chromeignoreSafeArea: truefromUIHostingControllerinit so the hosting view preserves real insets