facebook / react-native

A framework for building native applications using React
https://reactnative.dev
MIT License
119.45k stars 24.37k forks source link

RN Alert button sometimes renders in the upper-left corner of the screen (iOS) #45453

Open Willham12 opened 4 months ago

Willham12 commented 4 months ago

Description

Previous issue: https://github.com/facebook/react-native/issues/33889

RN Alert button appears on the left top corner.

Steps to reproduce

function openURL(url: string, error: string) {
    Linking.openURL(url).catch(() => showAlert(`${error} ${url}`));
}

function showAlert(
    title: string,
    message?: string,
    buttons?: AlertButton[],
    cancelable = true,
    onDismiss?: () => void
) {
    Alert.alert(title, message, buttons, {
        cancelable: cancelable,
        onDismiss: onDismiss,
        userInterfaceStyle: 'light',
    });

React Native Version

0.74.3

Affected Platforms

Runtime - iOS

Output of npx react-native info

info Fetching system and libraries information...
System:
  OS: macOS 14.5
  CPU: (16) x64 Intel(R) Core(TM) i9-9980HK CPU @ 2.40GHz
  Memory: 11.83 GB / 64.00 GB
  Shell:
    version: "5.9"
    path: /bin/zsh
Binaries:
  Node:
    version: 18.19.0
    path: ~/.nvm/versions/node/v18.19.0/bin/node
  Yarn:
    version: 4.2.2
    path: ~/.nvm/versions/node/v18.19.0/bin/yarn
  npm:
    version: 10.2.3
    path: ~/.nvm/versions/node/v18.19.0/bin/npm
  Watchman:
    version: 2024.06.10.00
    path: /usr/local/bin/watchman
Managers:
  CocoaPods:
    version: 1.15.2
    path: /usr/local/bin/pod
SDKs:
  iOS SDK:
    Platforms:
      - DriverKit 23.5
      - iOS 17.5
      - macOS 14.5
      - tvOS 17.5
      - visionOS 1.2
      - watchOS 10.5
  Android SDK:
    API Levels:
      - "33"
      - "34"
    Build Tools:
      - 33.0.0
      - 33.0.1
      - 34.0.0
      - 35.0.0
    System Images:
      - android-33 | Google APIs Intel x86_64 Atom
      - android-34 | Google APIs Intel x86_64 Atom
      - android-34 | Google Play Intel x86_64 Atom
    Android NDK: Not Found
IDEs:
  Android Studio: 2024.1 AI-241.18034.62.2411.12071903
  Xcode:
    version: 15.4/15F31d
    path: /usr/bin/xcodebuild
Languages:
  Java:
    version: 17.0.11
    path: /usr/local/bin/javac
  Ruby:
    version: 3.3.3
    path: /usr/local/opt/ruby/bin/ruby
npmPackages:
  "@react-native-community/cli": Not Found
  react:
    installed: 18.3.1
    wanted: 18.3.1
  react-native:
    installed: 0.74.3
    wanted: 0.74.3
  react-native-macos: Not Found
npmGlobalPackages:
  "*react-native*": Not Found
Android:
  hermesEnabled: true
  newArchEnabled: false
iOS:
  hermesEnabled: true
  newArchEnabled: false

Stacktrace or Logs

No crash

Reproducer

https://snack.expo.dev/PLgXKRrgtZIRIjiqFxkR-

Screenshots and Videos

https://github.com/facebook/react-native/issues/33889

rafaelctavares commented 2 months ago

Still happening in 0.75.2 Any updates on this?

bernborgess commented 2 months ago

What is the last version that hadn't this problem? I'm considering downgrading for a temporary fix.

bernborgess commented 2 months ago

This is the current comparison of Alert.alert("Test"); on android vs ios:

Android iOS
wpp image

Not how the "OK" is showing in the upper left corner.

satheeshwaran commented 2 months ago

We are also facing this issue with react-native@0.74.1

native iOS apps also have this issue when trying to present a modal on top of an existing alert

https://stackoverflow.com/questions/27028983/uialertcontroller-is-moved-to-buggy-position-at-top-of-screen-when-it-calls-pre

possible solution: https://stackoverflow.com/a/28731393

satheeshwaran commented 2 months ago

Looking at Xcode logs there is a UILayoutConstraint breaking due to which the alert is misplaced on the screen.

2024-09-16 15:03:45.398080+0530 wagering[1676:706712] [LayoutConstraints] Unable to simultaneously satisfy constraints.
    Probably at least one of the constraints in the following list is one you don't want. 
    Try this: 
        (1) look at each constraint and try to figure out which you don't expect; 
        (2) find the code that added the unwanted constraint or constraints and fix it. 
    (Note: If you're seeing NSAutoresizingMaskLayoutConstraints that you don't understand, refer to the documentation for the UIView property translatesAutoresizingMaskIntoConstraints) 
(
    "<NSAutoresizingMaskLayoutConstraint:0x2836b3b60 h=-&- v=-&- UITransitionView:0x10ac406f0.minY == 0   (active, names: '|':UIWindow:0x10ac39500 )>",
    "<NSAutoresizingMaskLayoutConstraint:0x2836b07d0 h=-&- v=-&- V:[UITransitionView:0x10ac406f0]-(0)-|   (active, names: '|':UIWindow:0x10ac39500 )>",
    "<NSAutoresizingMaskLayoutConstraint:0x2836b3840 h=--- v=--- UIWindow:0x10ac39500.height == 0   (active)>",
    "<NSLayoutConstraint:0x283686b20 _UIKeyboardLayoutAlignmentView:0x10ae22e90.bottom == UITransitionView:0x10ac406f0.bottom   (active)>",
    "<NSLayoutConstraint:0x2836c5ae0 _UIAlertControllerPhoneTVMacView:0x11102f800'New version available! '.bottom <= UIView:0x10ae46d00.bottom - 8   (active)>",
    "<NSLayoutConstraint:0x2836c7520 V:|-(0)-[UIView:0x10ae46d00]   (active, names: '|':UITransitionView:0x10ac406f0 )>",
    "<NSLayoutConstraint:0x2836c6120 UIView:0x10ae46d00.bottom == _UIKeyboardLayoutAlignmentView:0x10ae22e90.top   (active)>",
    "<NSLayoutConstraint:0x2836c4cd0 _UIAlertControllerPhoneTVMacView:0x11102f800'New version available! '.top >= UIView:0x10ae46d00.top + 47   (active)>"
)

Will attempt to recover by breaking constraint 
<NSLayoutConstraint:0x2836c5ae0 _UIAlertControllerPhoneTVMacView:0x11102f800'New version available! '.bottom <= UIView:0x10ae46d00.bottom - 8   (active)>

Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints to catch this in the debugger.
The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKitCore/UIView.h> may also be helpful.
2024-09-16 15:03:46.216950+0530 wagering[1676:706712] [LayoutConstraints] Unable to simultaneously satisfy constraints.
    Probably at least one of the constraints in the following list is one you don't want. 
    Try this: 
        (1) look at each constraint and try to figure out which you don't expect; 
        (2) find the code that added the unwanted constraint or constraints and fix it. 
    (Note: If you're seeing NSAutoresizingMaskLayoutConstraints that you don't understand, refer to the documentation for the UIView property translatesAutoresizingMaskIntoConstraints) 
(
    "<NSAutoresizingMaskLayoutConstraint:0x2836b3b60 h=-&- v=-&- UITransitionView:0x10ac406f0.minY == 0   (active, names: '|':UIWindow:0x10ac39500 )>",
    "<NSAutoresizingMaskLayoutConstraint:0x2836b07d0 h=-&- v=-&- V:[UITransitionView:0x10ac406f0]-(0)-|   (active, names: '|':UIWindow:0x10ac39500 )>",
    "<NSAutoresizingMaskLayoutConstraint:0x2836b3840 h=--- v=--- UIWindow:0x10ac39500.height == 0   (active)>",
    "<NSLayoutConstraint:0x283686b20 _UIKeyboardLayoutAlignmentView:0x10ae22e90.bottom == UITransitionView:0x10ac406f0.bottom   (active)>",
    "<NSLayoutConstraint:0x2836c4500 _UIAlertControllerPhoneTVMacView:0x11102f800'New version available! '.centerY == UILayoutGuide:0x282e81420'UIViewSafeAreaLayoutGuide'.centerY   (active)>",
    "<NSLayoutConstraint:0x2836c7520 V:|-(0)-[UIView:0x10ae46d00]   (active, names: '|':UITransitionView:0x10ac406f0 )>",
    "<NSLayoutConstraint:0x2836c6120 UIView:0x10ae46d00.bottom == _UIKeyboardLayoutAlignmentView:0x10ae22e90.top   (active)>",
    "<NSLayoutConstraint:0x2836c4cd0 _UIAlertControllerPhoneTVMacView:0x11102f800'New version available! '.top >= UIView:0x10ae46d00.top + 47   (active)>",
    "<NSLayoutConstraint:0x2836c68f0 'UIViewSafeAreaLayoutGuide-bottom' V:[UILayoutGuide:0x282e81420'UIViewSafeAreaLayoutGuide']-(0)-|   (active, names: '|':UIView:0x10ae46d00 )>",
    "<NSLayoutConstraint:0x2836c76b0 'UIViewSafeAreaLayoutGuide-top' V:|-(47)-[UILayoutGuide:0x282e81420'UIViewSafeAreaLayoutGuide']   (active, names: '|':UIView:0x10ae46d00 )>"
)

Will attempt to recover by breaking constraint 
<NSLayoutConstraint:0x2836c68f0 'UIViewSafeAreaLayoutGuide-bottom' V:[UILayoutGuide:0x282e81420'UIViewSafeAreaLayoutGuide']-(0)-|   (active, names: '|':UIView:0x10ae46d00 )>

Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints to catch this in the debugger.
The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKitCore/UIView.h> may also be helpful.
bernborgess commented 2 months ago

Looking at Xcode logs there is a UILayoutConstraint breaking due to which the alert is misplaced on the screen.

2024-09-16 15:03:45.398080+0530 wagering[1676:706712] [LayoutConstraints] Unable to simultaneously satisfy constraints.
  Probably at least one of the constraints in the following list is one you don't want. 
  Try this: 
      (1) look at each constraint and try to figure out which you don't expect; 
      (2) find the code that added the unwanted constraint or constraints and fix it. 
  (Note: If you're seeing NSAutoresizingMaskLayoutConstraints that you don't understand, refer to the documentation for the UIView property translatesAutoresizingMaskIntoConstraints) 
(
    "<NSAutoresizingMaskLayoutConstraint:0x2836b3b60 h=-&- v=-&- UITransitionView:0x10ac406f0.minY == 0   (active, names: '|':UIWindow:0x10ac39500 )>",
    "<NSAutoresizingMaskLayoutConstraint:0x2836b07d0 h=-&- v=-&- V:[UITransitionView:0x10ac406f0]-(0)-|   (active, names: '|':UIWindow:0x10ac39500 )>",
    "<NSAutoresizingMaskLayoutConstraint:0x2836b3840 h=--- v=--- UIWindow:0x10ac39500.height == 0   (active)>",
    "<NSLayoutConstraint:0x283686b20 _UIKeyboardLayoutAlignmentView:0x10ae22e90.bottom == UITransitionView:0x10ac406f0.bottom   (active)>",
    "<NSLayoutConstraint:0x2836c5ae0 _UIAlertControllerPhoneTVMacView:0x11102f800'New version available! '.bottom <= UIView:0x10ae46d00.bottom - 8   (active)>",
    "<NSLayoutConstraint:0x2836c7520 V:|-(0)-[UIView:0x10ae46d00]   (active, names: '|':UITransitionView:0x10ac406f0 )>",
    "<NSLayoutConstraint:0x2836c6120 UIView:0x10ae46d00.bottom == _UIKeyboardLayoutAlignmentView:0x10ae22e90.top   (active)>",
    "<NSLayoutConstraint:0x2836c4cd0 _UIAlertControllerPhoneTVMacView:0x11102f800'New version available! '.top >= UIView:0x10ae46d00.top + 47   (active)>"
)

Will attempt to recover by breaking constraint 
<NSLayoutConstraint:0x2836c5ae0 _UIAlertControllerPhoneTVMacView:0x11102f800'New version available! '.bottom <= UIView:0x10ae46d00.bottom - 8   (active)>

Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints to catch this in the debugger.
The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKitCore/UIView.h> may also be helpful.
2024-09-16 15:03:46.216950+0530 wagering[1676:706712] [LayoutConstraints] Unable to simultaneously satisfy constraints.
  Probably at least one of the constraints in the following list is one you don't want. 
  Try this: 
      (1) look at each constraint and try to figure out which you don't expect; 
      (2) find the code that added the unwanted constraint or constraints and fix it. 
  (Note: If you're seeing NSAutoresizingMaskLayoutConstraints that you don't understand, refer to the documentation for the UIView property translatesAutoresizingMaskIntoConstraints) 
(
    "<NSAutoresizingMaskLayoutConstraint:0x2836b3b60 h=-&- v=-&- UITransitionView:0x10ac406f0.minY == 0   (active, names: '|':UIWindow:0x10ac39500 )>",
    "<NSAutoresizingMaskLayoutConstraint:0x2836b07d0 h=-&- v=-&- V:[UITransitionView:0x10ac406f0]-(0)-|   (active, names: '|':UIWindow:0x10ac39500 )>",
    "<NSAutoresizingMaskLayoutConstraint:0x2836b3840 h=--- v=--- UIWindow:0x10ac39500.height == 0   (active)>",
    "<NSLayoutConstraint:0x283686b20 _UIKeyboardLayoutAlignmentView:0x10ae22e90.bottom == UITransitionView:0x10ac406f0.bottom   (active)>",
    "<NSLayoutConstraint:0x2836c4500 _UIAlertControllerPhoneTVMacView:0x11102f800'New version available! '.centerY == UILayoutGuide:0x282e81420'UIViewSafeAreaLayoutGuide'.centerY   (active)>",
    "<NSLayoutConstraint:0x2836c7520 V:|-(0)-[UIView:0x10ae46d00]   (active, names: '|':UITransitionView:0x10ac406f0 )>",
    "<NSLayoutConstraint:0x2836c6120 UIView:0x10ae46d00.bottom == _UIKeyboardLayoutAlignmentView:0x10ae22e90.top   (active)>",
    "<NSLayoutConstraint:0x2836c4cd0 _UIAlertControllerPhoneTVMacView:0x11102f800'New version available! '.top >= UIView:0x10ae46d00.top + 47   (active)>",
    "<NSLayoutConstraint:0x2836c68f0 'UIViewSafeAreaLayoutGuide-bottom' V:[UILayoutGuide:0x282e81420'UIViewSafeAreaLayoutGuide']-(0)-|   (active, names: '|':UIView:0x10ae46d00 )>",
    "<NSLayoutConstraint:0x2836c76b0 'UIViewSafeAreaLayoutGuide-top' V:|-(47)-[UILayoutGuide:0x282e81420'UIViewSafeAreaLayoutGuide']   (active, names: '|':UIView:0x10ae46d00 )>"
)

Will attempt to recover by breaking constraint 
<NSLayoutConstraint:0x2836c68f0 'UIViewSafeAreaLayoutGuide-bottom' V:[UILayoutGuide:0x282e81420'UIViewSafeAreaLayoutGuide']-(0)-|   (active, names: '|':UIView:0x10ae46d00 )>

Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints to catch this in the debugger.
The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKitCore/UIView.h> may also be helpful.

Did you find out how to reproduce it in the React Native API of the ui?

satheeshwaran commented 2 months ago

One way to replicate this is to show multiple alerts and move the app foreground ->background->foreground numerous times.

dovhanrg commented 2 months ago

I can reproduce it when firing alert when app in the background(not killed)

hasanalicansu commented 2 weeks ago

Same goes for modal. I am using modal from React-native. My modal is a global modal in App.ts. Modal is controlled by ref. Only on ios

new_arch enabled, react-native: 0.75.4

https://github.com/user-attachments/assets/2d4373d0-f198-4be7-8d78-75bba59d587a

remacr commented 1 week ago

The issue is still present for Modal and Alert components in Android as well on version 0.76.1 with newArch enabled and disabled.

faljabi commented 1 week ago

I noticed it happens for me whenever I am mirroring my phone for a presentation. Once I turn off mirroring my iPhone it is displayed in the center.

Tencryn commented 20 hours ago

The issue is still present for Modal and Alert components in Android as well on version 0.76.1 with newArch enabled and disabled.

Can confirm, this is still occurring on 0.76.3 also. I had a global modal which is completely unusable now.