Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[iOS] Navigation Bar Size Issue with codegenNativeComponent and modalPresentationStyle: .pageSheet in React Native #47600

Open
dp221125 opened this issue Nov 14, 2024 · 17 comments
Labels
Component: Modal Needs: Triage 🔍 Type: New Architecture Issues and PRs related to new architecture (Fabric/Turbo Modules)

Comments

@dp221125
Copy link

dp221125 commented Nov 14, 2024

Description

In a React Native environment, I'm using codegenNativeComponent to display a native screen. On this native screen, when I present a new screen with modalPresentationStyle set to .pageSheet, the navigation bar size becomes abnormal. Although this might appear to be an issue with the native side because I’m using native screens, I don’t experience this problem when presenting a modal with .pageSheet without React Native.

Steps to reproduce

  1. Clone the repository: RNPlayground.
  2. Navigate to the RNPlayground/react-native-playground folder.
  3. Run yarn install.
  4. Return to the root directory and run pod install (or bundle install followed by bundle exec pod install if using Bundler).
  5. Open RNPlayground.xcworkspace and build the project for an iPhone targeting iOS 16 or 17.
  6. When the app launches, tap the "Show Detail" button displayed on the screen.

React Native Version

0.76.1

Affected Platforms

Runtime - iOS

Areas

Other (please specify)

Output of npx react-native info

System:
  OS: macOS 14.7
  CPU: (10) arm64 Apple M1 Pro
  Memory: 227.33 MB / 32.00 GB
  Shell:
    version: "5.9"
    path: /bin/zsh
Binaries:
  Node:
    version: 20.17.0
    path: ~/.asdf/installs/nodejs/20.17.0/bin/node
  Yarn:
    version: 4.5.0
    path: ~/.asdf/installs/nodejs/20.17.0/bin/yarn
  npm:
    version: 10.8.2
    path: ~/.asdf/plugins/nodejs/shims/npm
  Watchman: Not Found
Managers:
  CocoaPods:
    version: 1.16.2
    path: /Users/seokho/.rbenv/shims/pod
SDKs:
  iOS SDK:
    Platforms:
      - DriverKit 24.0
      - iOS 18.0
      - macOS 15.0
      - tvOS 18.0
      - visionOS 2.0
      - watchOS 11.0
  Android SDK: Not Found
IDEs:
  Android Studio: 2022.2 AI-222.4459.24.2221.10121639
  Xcode:
    version: 16.0/16A242
    path: /usr/bin/xcodebuild
Languages:
  Java: Not Found
  Ruby:
    version: 3.1.3
    path: /Users/seokho/.rbenv/shims/ruby
npmPackages:
  "@react-native-community/cli":
    installed: 15.0.0
    wanted: 15.0.0
  react:
    installed: 18.3.1
    wanted: 18.3.1
  react-native:
    installed: 0.76.1
    wanted: 0.76.1
  react-native-macos: Not Found
npmGlobalPackages:
  "*react-native*": Not Found
Android:
  hermesEnabled: Not found
  newArchEnabled: Not found
iOS:
  hermesEnabled: true
  newArchEnabled: true

Stacktrace or Logs

Not a crash, not a failure, just a UI bug.

Reproducer

https://github.com/dp221125/RNPlayground

Screenshots and Videos

React Native

Simulator.Screen.Recording.-.iPhone.13.mini.-.2024-11-14.at.11.35.55.mp4

iOS Native (not using React Native)

Simulator.Screen.Recording.-.iPhone.13.mini.-.2024-11-14.at.11.34.42.mp4

ScreenShot

image
@dp221125 dp221125 added Needs: Triage 🔍 Type: New Architecture Issues and PRs related to new architecture (Fabric/Turbo Modules) labels Nov 14, 2024
@dp221125 dp221125 changed the title Navigation Bar Size Issue with codegenNativeComponent and modalPresentationStyle: .pageSheet in React Native [iOS] Navigation Bar Size Issue with codegenNativeComponent and modalPresentationStyle: .pageSheet in React Native Nov 14, 2024
@ChronoByteCosmonaut
Copy link

ChronoByteCosmonaut commented Nov 20, 2024

I have an issue with the onLayout on iOS where the screen height is not measured correctly on the first render using the Dimensios.get("screen").height!

@coado
Copy link
Contributor

coado commented Nov 20, 2024

I have an issue with the onLayout on iOS where the screen height is not measured correctly on the first render using the Dimensios.get("screen").height!

Is it also the case on iOS 18?

@thuongtv-vn
Copy link

I got a similar issue on ios 18

@coado
Copy link
Contributor

coado commented Nov 22, 2024

Hey @thuongtv-vn, the above issue does not appear on iOS 18. Is it also something with a modal that you are experiencing?

@dp221125
Copy link
Author

Umm.. It is still occurring intermittently, even on iOS 18.

@coado
Copy link
Contributor

coado commented Nov 25, 2024

Umm.. It is still occurring intermittently, even on iOS 18.

Hmm that's interesting. For me it's seems to be fine when I run it on iOS 18.

@coado
Copy link
Contributor

coado commented Nov 28, 2024

I've tried to investigate this one, but as of now, I am not sure why this happens. Repros for other related issues mentioned above would probably be extremely helpful 🙏

@cipolleschi
Copy link
Contributor

@dp221125 Sorry if this took that much time.

I think that the current setup and example is not the right one and it is a bit confusing.
What's your goal? What are you trying to do?

I don't think that that's the right way to achieve what you want to achieve.

Custom components, the one that you can create with codegenNativeComponent are not meant to be full pages that you present from other view controller. Custom components are usually small pieces of UI that you can compose in different screens by using Javascript and you need custom components ONLY when you have to bind some platform-specific components like UISwitch or similar, not for general stuff like UIView.

For what you want achieve from the reproducer you shared, we have a guide in the website (Integrating with An Existing app ) that we updated recently and that will let you load a React Native screen in an existing app.

Once the screen is loaded, you can use regular React Native concepts and libraries to build your experience.

@dp221125
Copy link
Author

Custom components, the one that you can create with codegenNativeComponent are not meant to be full pages that you present from other view controller. Custom components are usually small pieces of UI that you can compose in different screens by using Javascript and you need custom components ONLY when you have to bind some platform-specific components like UISwitch or similar, not for general stuff like UIView.

@cipolleschi

Hello, thank you for your response.

First of all, we currently have an app that is fully implemented natively.
Therefore, the following tasks need to be performed:

When the app is launched, the RN app should be loaded from the AppDelegate.
In other words, the screen the user encounters when the app first starts will consist of React Native screens.

From the React Native screens, when a specific action is performed (for example, pressing a particular button on the screen), the app needs to navigate to an already implemented native screen.
(Here, the "native screen" refers to a screen implemented by subclassing UIViewController.)
Rewriting all native screens in React Native would take considerable time and is not a feasible action for now.

Therefore, I expect to use codegenNativeComponent to provide users with the native screens (implemented as UIViewController) from React Native.

@cipolleschi
Copy link
Contributor

If I understand correctly:

  • The app should start presenting a React Native screen
  • After the user press some button in the RN Screen, they have to navigate to some other screen in your app, you already implemented natively.

Is this correct?
If yes, I still don't think that codegenNativeComponent is the right approach here. As I mention, codegenNativeComponent needs to be used to create isolated components that you can reuse and combine in React Native screens.

One way you can achieve what you need is by implementing a module, instead of a component, that could be a Coordinator.

  1. Create a Native Module in React Native that exposes a method navigateTo() (this is the guide on how to create modules: https://reactnative.dev/docs/next/fabric-native-components-introduction).
  2. In native, the module can access the AppDelegate using the RCTPresentedViewController from RCTUtils.h to retrieve the ViewController that is presenting React Native or RCTSharedApplication to retrieve the UIApplication class
  3. Use the native navigation API to present your native view controllers.

@CHOIMINSEOK
Copy link
Contributor

CHOIMINSEOK commented Jan 15, 2025

I �encountered the same issue when navigating "react-native screen" in a brown field app(new archi mode). This only happens when using modal presentation style of react-navigation

I suspect something might be happening in RNScreens.. but no clue so far. Could you give me some ideas to investigate this issue? @cipolleschi

Screen.Recording.2025-01-15.at.23.31.17.mov

I'm using following versions :

"react-native": "0.76.5",
"@react-navigation/native": "^7.0.14",
"@react-navigation/native-stack": "^7.2.0",
"react-native-screens": "^4.4.0",

@cipolleschi
Copy link
Contributor

@CHOIMINSEOK have you tried to open an issue in RNScreens repo? Software Mansion's people are pretty responsive and on top of New Architecture stuff. They knows the library better, so they could help you better and faster!

@CHOIMINSEOK
Copy link
Contributor

I will, Thank you @cipolleschi

Anyway, @dp221125 and I are actually in same project. We also expected that there's something wrong on the way we embed existing native ViewController on top of RN App like you mensioned above #47600 (comment) , but it's still happening even our navigation works on react-navigation without any Native Component. Maybe some configurations of native part affect on this... 🤔

@cipolleschi
Copy link
Contributor

If you can provide a reproducer using this template, where you can add RNScreens alone, we can look into it. In general, we need isolated examples we can use to pinpoint precisely the issue and resolve it.

@CHOIMINSEOK
Copy link
Contributor

The issue was caused by the behavior of SafeAreaInset. On iOS, pages presented using a modal style don’t require a top safe area margin because the system handles it automatically. However, useSafeAreaInsets always returns a fixed top inset value regardless of the presentation style of the target page. We resolved the issue by removing the top inset.

AppAndFlow/react-native-safe-area-context#504

@cipolleschi
Copy link
Contributor

So this is a problem of react-native-safe-area-context or in the app code, more than of ReactNative itself, right @CHOIMINSEOK ?

@CHOIMINSEOK
Copy link
Contributor

I believe there are two issues:

  1. When embedding a native ViewController within a NativeModule, unexpected top padding is also added.

  2. When using the top inset from react-native-safe-area on a modal-presented page in react-navigation, unexpected top padding appears.

The second issue can be resolved by removing the top inset on the page. However, the first issue, which is the original problem discussed in this thread, remains unresolved.

Our team no longer needs to address it. If no one else is interested in tackling the original issue, I think we could close this thread.

Thanks for your help, @cipolleschi! 😊

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Component: Modal Needs: Triage 🔍 Type: New Architecture Issues and PRs related to new architecture (Fabric/Turbo Modules)
Projects
None yet
Development

No branches or pull requests

7 participants