Skip to content

fix(iOS) - Prevent SwiftUI based filter from insetting content by the safe area - #58349

Closed
intergalacticspacehighway wants to merge 2 commits into
react:mainfrom
intergalacticspacehighway:fix/swiftui-filter-safe-area-regions
Closed

fix(iOS) - Prevent SwiftUI based filter from insetting content by the safe area#58349
intergalacticspacehighway wants to merge 2 commits into
react:mainfrom
intergalacticspacehighway:fix/swiftui-filter-safe-area-regions

Conversation

@intergalacticspacehighway

Copy link
Copy Markdown
Contributor

Summary:

When a filter style is passed to a View, it can shift the View by safe area insets if it overlaps a safe area edge. Filter style should not affect layout. Also fixes - #57642

Unset safeAreaRegions on the hosting controller to opt out of implicit safe area insets. Below iOS 16.4 safeAreaRegions does not exist so it requires Obj-C swizzling hack as noted here - #57643. Hence, proper fix requires gating the filter feature to iOS 16.4. We can mention it in the documentation on release.

Changelog:

[IOS] [FIXED] - Fix views with a filter having their content offset by the safe area insets

Test Plan:

  • Set releaseLevel to canary.
  • Render <View style={{width: 100, height: 100, backgroundColor:"red", filter:[{blur: 10}]}} /> in RNTester, make sure it renders on top of the screen.
  • View renders as expected on first mount.
  • Change height or width, it will shift the view by safe area inset. It requires layout update because RCTMountingManager calls finalizeUpdates before calling mountChildComponentView, so on first mount the hosting view has no window and its safe area insets are zero.
Before After
Filtered content pushed down by the top safe area inset Filtered content aligned with the view bounds
Content is offset down and shrunk by the top inset Content fills the view

cc - @jorge-cab

UIHostingController insets its root view by the safe area, so a filtered view
had its content moved down and shrunk whenever the view overlapped a safe area
edge. A filter must not affect layout.

Set `safeAreaRegions = []` on the hosting controller to opt out, and gate the
SwiftUI filter container at iOS 16.4, the first version where that property
exists. Below 16.4 the filters that need the container stay no-ops, which
matches the behavior before `enableSwiftUIBasedFilters` existed.

`safeAreaRegions` is declared `@available(iOS 16.4, tvOS 16.4, *)`, so both
checks name tvOS. Without the tvOS clause the Swift file fails to build for
tvOS.
@meta-cla meta-cla Bot added the CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. label Sep 4, 2026
@facebook-github-tools facebook-github-tools Bot added the Shared with Meta Applied via automation to indicate that an Issue or Pull Request has been shared with the team. label Sep 4, 2026
Comment thread packages/react-native/ReactApple/RCTSwiftUI/RCTSwiftUIContainerView.swift Outdated
@meta-codesync

meta-codesync Bot commented Sep 8, 2026

Copy link
Copy Markdown

@cipolleschi has imported this pull request. If you are a Meta employee, you can view this in D119153463.

@meta-codesync meta-codesync Bot closed this in fea820f Sep 9, 2026
@meta-codesync meta-codesync Bot added the Merged This PR has been merged. label Sep 9, 2026
@meta-codesync

meta-codesync Bot commented Sep 9, 2026

Copy link
Copy Markdown

@cipolleschi merged this pull request in fea820f.

shashikant-panchal pushed a commit to shashikant-panchal/react-native that referenced this pull request Sep 10, 2026
…he safe area (react#58349)

Summary:
When a `filter` style is passed to a `View`, it can shift the `View` by safe area insets if it overlaps a safe area edge. Filter style should not affect layout. Also fixes - react#57642

Unset [safeAreaRegions](https://developer.apple.com/documentation/swiftui/uihostingcontroller/safearearegions) on the hosting controller to opt out of implicit safe area insets. Below iOS 16.4 `safeAreaRegions` does not exist so it requires Obj-C swizzling hack as noted here - react#57643. Hence, proper fix requires gating the filter feature to iOS 16.4. We can mention it in the documentation on release.

## Changelog:

[IOS] [FIXED] - Fix views with a filter having their content offset by the safe area insets

<!-- Help reviewers and the release process by writing your own changelog entry.

Pick one each for the category and type tags:

For more details, see:
https://reactnative.dev/contributing/changelogs-in-pull-requests

Pull Request resolved: react#58349

Test Plan:
- Set `releaseLevel` to canary.
- Render `<View style={{width: 100, height: 100, backgroundColor:"red", filter:[{blur: 10}]}} />` in RNTester, make sure it renders on top of the screen.
- View renders as expected on first mount.
- Change height or width, it will shift the view by safe area inset. It requires layout update because RCTMountingManager calls `finalizeUpdates` before calling `mountChildComponentView`, so on first mount the hosting view has no window and its safe area insets are zero.

| Before | After |
| --- | --- |
| <img width="200" alt="Filtered content pushed down by the top safe area inset" src="https://github.com/user-attachments/assets/49905f7b-0a82-4958-91d2-e89c852e5a93" /> | <img width="200" alt="Filtered content aligned with the view bounds" src="https://github.com/user-attachments/assets/85848179-43fc-42f4-9271-1093413ad42d" /> |
| Content is offset down and shrunk by the top inset | Content fills the view |

cc - jorge-cab

Reviewed By: christophpurrer

Differential Revision: D119153463

Pulled By: cipolleschi

fbshipit-source-id: edabd933b4928dd023109eba5d09b6447256615f
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. Merged This PR has been merged. Shared with Meta Applied via automation to indicate that an Issue or Pull Request has been shared with the team.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants