Skip to content

[ui][ios] - Add ignoreSafeAreaKeyboardInsets prop to Host#41302

Merged
intergalacticspacehighway merged 9 commits intomainfrom
disable-safe-area-insets
Dec 10, 2025
Merged

[ui][ios] - Add ignoreSafeAreaKeyboardInsets prop to Host#41302
intergalacticspacehighway merged 9 commits intomainfrom
disable-safe-area-insets

Conversation

@intergalacticspacehighway
Copy link
Copy Markdown
Contributor

@intergalacticspacehighway intergalacticspacehighway commented Nov 28, 2025

Why

In some usecases we want to control the safe area insets in RN instead of allowing SwiftUI to handle it e.g. custom keyboard handling with keyboard controller library. Demo - https://exponent-internal.slack.com/archives/C08CCJ60467/p1764263300639479

Blogpost for supporting on iOS < 16.4 (it is a hack but works) - https://steipete.me/posts/2020/disabling-keyboard-avoidance-in-swiftui-uihostingcontroller

This PR adds ignoreSafeAreaKeyboardInsets prop to Host. It is configurable per Host. When it is set, SwiftUI content will ignore safe area insets.

How

UIHostingController adds safe area insets for SwiftUI views. These insets are configurable for some Views using ignoreSafeAreaInsets modifier. But I noticed that TextField does not respect this modifier and will still show keyboard avoidance behaviour. UIHostingController has a configurable property to disable safe area insets for all the SwiftUI contents, which can be used for such TextField cases. However this property only works for iOS 16.4 and above. There are some hacks to support it in <16.4 here and here. We can maybe add that.

Test Plan

Before/After. Added the repro in a new screen

Simulator.Screen.Recording.-.iPhone.17.Pro.-.2025-11-28.at.23.35.52.mov
Simulator.Screen.Recording.-.iPhone.17.Pro.-.2025-11-28.at.23.35.22.mov

Checklist

@expo-bot expo-bot added the bot: suggestions ExpoBot has some suggestions label Nov 28, 2025
@expo-bot
Copy link
Copy Markdown
Collaborator

expo-bot commented Nov 28, 2025

The Pull Request introduced fingerprint changes against the base commit: 80ffc01

Fingerprint diff
[
  {
    "op": "changed",
    "beforeSource": {
      "type": "dir",
      "filePath": "../../packages/expo-modules-core",
      "reasons": [
        "expoAutolinkingIos",
        "expoAutolinkingAndroid",
        "expoAutolinkingIos"
      ],
      "hash": "e2a72efbe83f07203ad8fea8169e7c5a5071c412"
    },
    "afterSource": {
      "type": "dir",
      "filePath": "../../packages/expo-modules-core",
      "reasons": [
        "expoAutolinkingIos",
        "expoAutolinkingAndroid",
        "expoAutolinkingIos"
      ],
      "hash": "8c150259cda0511d4fd81a698b97eac6d89f2282"
    }
  },
  {
    "op": "changed",
    "beforeSource": {
      "type": "dir",
      "filePath": "../../packages/expo-ui/ios",
      "reasons": [
        "expoAutolinkingIos"
      ],
      "hash": "c945f781ee51d418b9abfb15e9e71fd650a294b3"
    },
    "afterSource": {
      "type": "dir",
      "filePath": "../../packages/expo-ui/ios",
      "reasons": [
        "expoAutolinkingIos"
      ],
      "hash": "8cc342f73b25a8e6f368759e9d09ac3f1ea03e0c"
    }
  }
]

Generated by PR labeler 🤖

@intergalacticspacehighway intergalacticspacehighway changed the title [ui][ios] - Add ignoreSafeAreaInsets prop to Host [ui][ios] - Add ignoreKeyboardSafeAreaInsets prop to Host Dec 1, 2025
@intergalacticspacehighway intergalacticspacehighway changed the title [ui][ios] - Add ignoreKeyboardSafeAreaInsets prop to Host [ui][ios] - Add ignoreSafeAreaKeyboardInsets prop to Host Dec 1, 2025
@intergalacticspacehighway intergalacticspacehighway marked this pull request as ready for review December 1, 2025 14:02
@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Dec 1, 2025

Subscribed to pull request

File Patterns Mentions
packages/expo-modules-core/** @Kudo, @lukmccall
packages/expo-ui/** @aleqsio, @behenate, @douglowder

Generated by CodeMention

@expo-bot expo-bot added bot: passed checks ExpoBot has nothing to complain about and removed bot: suggestions ExpoBot has some suggestions labels Dec 1, 2025
@intergalacticspacehighway intergalacticspacehighway merged commit e732ad1 into main Dec 10, 2025
19 of 20 checks passed
@intergalacticspacehighway intergalacticspacehighway deleted the disable-safe-area-insets branch December 10, 2025 04:53
@vicovictor
Copy link
Copy Markdown

I had just upgraded to expo 54.0.28 and @expo/ui 0.2.0-beta.10, which the latter included this change and #41519. I tried to clean build, and got these errors below. Do you happen to know why? Wondering if there's a solution now. Thanks!

❌  (node_modules/@expo/ui/ios/HostView.swift:34:72)

  32 | }
  33 | 
> 34 | internal final class HostViewProps: ExpoSwiftUI.ViewProps, ExpoSwiftUI.SafeAreaControllable {
     |                                                                        ^ 'SafeAreaControllable' is not a member type of struct 'ExpoModulesCore.ExpoSwiftUI'
  35 |   @Field var useViewportSizeMeasurement: Bool = false
  36 |   @Field var colorScheme: ExpoColorScheme?
  37 |   @Field var layoutDirection: ExpoLayoutDirection = .leftToRight


❌  (node_modules/@expo/ui/ios/RNHostView.swift:5:54)

  3 | import ExpoModulesCore
  4 | 
> 5 | public final class RNHostView: ExpoView, ExpoSwiftUI.RNHostViewProtocol {
    |                                                      ^ 'RNHostViewProtocol' is not a member type of struct 'ExpoModulesCore.ExpoSwiftUI'
  6 |   public required init(appContext: AppContext? = nil) {
  7 |     super.init(appContext: appContext)
  8 |     ExpoUITouchHandlerHelper.createAndAttachTouchHandler(for: self)

@intergalacticspacehighway
Copy link
Copy Markdown
Contributor Author

@vicovictor we'll be cherrypicking these changes in upcoming expo patch release. Can you stay on 0.2.0-beta.9 till then?

aleqsio pushed a commit that referenced this pull request Dec 22, 2025
# Why

In some usecases we want to control the safe area insets in RN instead
of allowing SwiftUI to handle it e.g. custom keyboard handling with
keyboard controller library. Demo -
https://exponent-internal.slack.com/archives/C08CCJ60467/p1764263300639479

Blogpost for supporting on iOS < 16.4 (it is a hack but works) -
https://steipete.me/posts/2020/disabling-keyboard-avoidance-in-swiftui-uihostingcontroller

This PR adds `ignoreSafeAreaKeyboardInsets` prop to Host. It is
configurable per Host. When it is set, SwiftUI content will ignore safe
area insets.

<!--
Please describe the motivation for this PR, and link to relevant GitHub
issues, forums posts, or feature requests.
-->

# How

UIHostingController adds safe area insets for SwiftUI views. These
insets are configurable for some Views using `ignoreSafeAreaInsets`
modifier. But I noticed that TextField does not respect this modifier
and will still show keyboard avoidance behaviour. UIHostingController
has a configurable
[property](https://developer.apple.com/documentation/swiftui/uihostingcontroller/safearearegions)
to disable safe area insets for all the SwiftUI contents, which can be
used for such TextField cases. However this property only works for iOS
16.4 and above. There are some hacks to support it in <16.4
[here](https://developer.apple.com/forums/thread/658432) and
[here](https://gist.github.com/steipete/da72299613dcc91e8d729e48b4bb582c).
We can maybe add that.
<!--
How did you build this feature or fix this bug and why?
-->

# Test Plan

Before/After. Added the repro in a new screen


https://github.com/user-attachments/assets/552eb6e1-64db-4c45-9185-cdb8eb6b3986



https://github.com/user-attachments/assets/a625a5b4-5545-4edc-a654-2ac37642079e



<!--
Please describe how you tested this change and how a reviewer could
reproduce your test, especially if this PR does not include automated
tests! If possible, please also provide terminal output and/or
screenshots demonstrating your test/reproduction.
-->

# Checklist

<!--
Please check the appropriate items below if they apply to your diff.
-->

- [x] I added a `changelog.md` entry and rebuilt the package sources
according to [this short
guide](https://github.com/expo/expo/blob/main/CONTRIBUTING.md#-before-submitting)
- [x] This diff will work correctly for `npx expo prebuild` & EAS Build
(eg: updated a module plugin).
- [x] Conforms with the [Documentation Writing Style
Guide](https://github.com/expo/expo/blob/main/guides/Expo%20Documentation%20Writing%20Style%20Guide.md)
@noahc1510
Copy link
Copy Markdown

I had just upgraded to expo 54.0.28 and @expo/ui 0.2.0-beta.10, which the latter included this change and #41519. I tried to clean build, and got these errors below. Do you happen to know why? Wondering if there's a solution now. Thanks!

❌  (node_modules/@expo/ui/ios/HostView.swift:34:72)

  32 | }
  33 | 
> 34 | internal final class HostViewProps: ExpoSwiftUI.ViewProps, ExpoSwiftUI.SafeAreaControllable {
     |                                                                        ^ 'SafeAreaControllable' is not a member type of struct 'ExpoModulesCore.ExpoSwiftUI'
  35 |   @Field var useViewportSizeMeasurement: Bool = false
  36 |   @Field var colorScheme: ExpoColorScheme?
  37 |   @Field var layoutDirection: ExpoLayoutDirection = .leftToRight


❌  (node_modules/@expo/ui/ios/RNHostView.swift:5:54)

  3 | import ExpoModulesCore
  4 | 
> 5 | public final class RNHostView: ExpoView, ExpoSwiftUI.RNHostViewProtocol {
    |                                                      ^ 'RNHostViewProtocol' is not a member type of struct 'ExpoModulesCore.ExpoSwiftUI'
  6 |   public required init(appContext: AppContext? = nil) {
  7 |     super.init(appContext: appContext)
  8 |     ExpoUITouchHandlerHelper.createAndAttachTouchHandler(for: self)

I found the same error in expo 54.0.31 and expo/ui 0.2.0-beta.10
Is there any updates here? Which version will fix this problem?

intergalacticspacehighway added a commit that referenced this pull request Jan 28, 2026
# Why

`Host` adds safe area insets to SwiftUI views causing such issues -
#42576. We had added
[`ignoreSafeAreaKeyboardInsets`](#41302)
for similar reasons but it was handling only keyboard insets.


<!--
Please describe the motivation for this PR, and link to relevant GitHub
issues, forums posts, or feature requests.
-->

# How

Adds `ignoreSafeArea` prop to `Host` which can be used to ignore all
insets as well as keyboard insets.
<!--
How did you build this feature or fix this bug and why?
-->

# Test Plan

Tested the repro shared in the reported
[issue](#42576). It gets fixed on
passing `ignoreSafeArea` prop to `Host`


https://github.com/user-attachments/assets/17bfb493-07d1-455a-8f93-bc5d4bbcb92f


<!--
Please describe how you tested this change and how a reviewer could
reproduce your test, especially if this PR does not include automated
tests! If possible, please also provide terminal output and/or
screenshots demonstrating your test/reproduction.
-->

# Checklist

<!--
Please check the appropriate items below if they apply to your diff.
-->

- [x] I added a `changelog.md` entry and rebuilt the package sources
according to [this short
guide](https://github.com/expo/expo/blob/main/CONTRIBUTING.md#-before-submitting)
- [x] This diff will work correctly for `npx expo prebuild` & EAS Build
(eg: updated a module plugin).
- [x] Conforms with the [Documentation Writing Style
Guide](https://github.com/expo/expo/blob/main/guides/Expo%20Documentation%20Writing%20Style%20Guide.md)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bot: fingerprint changed bot: passed checks ExpoBot has nothing to complain about

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants