Environment
| Package |
Version |
| react-native-pager-view |
8.0.0 – 8.0.2 (current master) |
| react-native |
0.85.x |
| Architecture |
New Architecture (Fabric), iOS |
Description
On the New Architecture iOS path, content rendered inside a PagerView page does not receive the screen's safe area insets. UI that relies on the safe area (content near the notch / Dynamic Island / home indicator) ends up with zero insets and can be clipped or sit under system UI.
Root cause
In ios/PagerViewProvider.swift, the SwiftUI host is created with ignoreSafeArea: true:
self.hostingController = UIHostingController(
rootView: PagerView(props: props, delegate: delegate),
ignoreSafeArea: true
)
That convenience initializer (in ios/Extensions.swift) calls disableSafeArea(), which dynamically subclasses the hosting controller's view to return safeAreaInsets = .zero. This makes the pager render edge-to-edge, but as a side effect the hosted UIKit / React Native child views also report safeAreaInsets = .zero, so any RN content inside a page loses the real safe area.
RepresentableView (the wrapper for each page) is a plain UIViewRepresentable that just adds the RN view into a wrapper UIView, so there is nothing to restore the insets the host stripped.
Expected behavior
The pager can be edge-to-edge, but the child pages should still receive the correct safe area insets (matching a non-paged screen), so RN layouts using useSafeAreaInsets() / SafeAreaView behave the same inside and outside the pager.
Proposed fix
- Use SwiftUI
.ignoresSafeArea() on the TabView to keep the pager edge-to-edge.
- Render each child through a
UIViewControllerRepresentable (PageChildViewController) that re-injects the hosting view's real safe area insets via additionalSafeAreaInsets in viewDidLayoutSubviews().
- Drop
ignoreSafeArea: true from setupView() since the controller-level safe-area disabling is no longer needed.
PR: #1085
Environment
master)Description
On the New Architecture iOS path, content rendered inside a
PagerViewpage does not receive the screen's safe area insets. UI that relies on the safe area (content near the notch / Dynamic Island / home indicator) ends up with zero insets and can be clipped or sit under system UI.Root cause
In
ios/PagerViewProvider.swift, the SwiftUI host is created withignoreSafeArea: true:That convenience initializer (in
ios/Extensions.swift) callsdisableSafeArea(), which dynamically subclasses the hosting controller's view to returnsafeAreaInsets = .zero. This makes the pager render edge-to-edge, but as a side effect the hosted UIKit / React Native child views also reportsafeAreaInsets = .zero, so any RN content inside a page loses the real safe area.RepresentableView(the wrapper for each page) is a plainUIViewRepresentablethat just adds the RN view into a wrapperUIView, so there is nothing to restore the insets the host stripped.Expected behavior
The pager can be edge-to-edge, but the child pages should still receive the correct safe area insets (matching a non-paged screen), so RN layouts using
useSafeAreaInsets()/SafeAreaViewbehave the same inside and outside the pager.Proposed fix
.ignoresSafeArea()on theTabViewto keep the pager edge-to-edge.UIViewControllerRepresentable(PageChildViewController) that re-injects the hosting view's real safe area insets viaadditionalSafeAreaInsetsinviewDidLayoutSubviews().ignoreSafeArea: truefromsetupView()since the controller-level safe-area disabling is no longer needed.PR: #1085