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

Alert disappears when modal gets hidden (re-rendered with visible=false) #22237

Closed
sryze opened this issue Nov 11, 2018 · 4 comments
Closed

Alert disappears when modal gets hidden (re-rendered with visible=false) #22237

sryze opened this issue Nov 11, 2018 · 4 comments
Labels

Comments

@sryze
Copy link
Contributor

sryze commented Nov 11, 2018

Environment

  React Native Environment Info:
    System:
      OS: macOS High Sierra 10.13.6
      CPU: (4) x64 Intel(R) Core(TM) i5-7500 CPU @ 3.40GHz
      Memory: 318.71 MB / 16.00 GB
      Shell: 5.6.2 - /usr/local/bin/zsh
    Binaries:
      Node: 11.0.0 - /usr/local/bin/node
      Yarn: 1.12.1 - /usr/local/bin/yarn
      npm: 6.4.1 - /usr/local/bin/npm
      Watchman: 4.9.0 - /usr/local/bin/watchman
    SDKs:
      iOS SDK:
        Platforms: iOS 11.4, macOS 10.13, tvOS 11.4, watchOS 4.3
    IDEs:
      Android Studio: 3.2 AI-181.5540.7.32.5056338
      Xcode: 9.4.1/9F2000 - /usr/bin/xcodebuild
    npmPackages:
      react: 16.6.0-alpha.8af6728 => 16.6.0-alpha.8af6728
      react-native: 0.57.4 => 0.57.4
    npmGlobalPackages:
      create-react-native-app: 1.0.0
      react-native-cli: 2.0.1

Description

On iOS when an alert is shown on top of a modal and you hide the modal (by changing its visible prop via state) the alert also gets dismissed at the same time.

Reproducible Demo

Demo project:

demo.zip

Video of the bug:

https://drive.google.com/file/d/1eV7p9F_GLZDMWeoVZJrkcGqOXhL8ViYR/view?usp=sharing

@sryze
Copy link
Contributor Author

sryze commented Nov 23, 2018

This issue affects modal view controllers in general, not just alerts.

@sryze
Copy link
Contributor Author

sryze commented Dec 15, 2018

I did some debugging and found that because the UIAlertController is presented on top of a modal it becomes the presentedViewController of the modal's RCTModalHostViewController. When a modal gets dimissed RCTModalHostViewManager calls:

// viewController == RCTModalHostViewController instance
[viewController dismissViewControllerAnimated:animated completion:completionBlock];

which hides the alert view controller and the modal view controller remains visible. The documentation for dismissViewController:animated: says:

Dismisses the view controller that was presented modally by the view controller.

i.e. it dismisses the view controller presented by the receiver (RCTModalHostViewController in this case).

I think as a solution UIAlertController should be presented not by the modal but by a higher level view controller, so that when an alert is shown the modal will be dismissed automatically (not certain about the last part).

@sryze
Copy link
Contributor Author

sryze commented Dec 15, 2018

This patch fixes the dismissal of modals when there are view controllers presented on top of them:

--- a/node_modules/react-native/React/Views/RCTModalHostViewManager.m
+++ b/node_modules/react-native/React/Views/RCTModalHostViewManager.m
@@ -89,7 +89,13 @@ RCT_EXPORT_MODULE()
   if (_dismissalBlock) {
     _dismissalBlock([modalHostView reactViewController], viewController, animated, completionBlock);
   } else {
-    [viewController dismissViewControllerAnimated:animated completion:completionBlock];
+    if (viewController.presentedViewController && viewController.presentingViewController) {
+      // Ask the presenting view controller to dismiss any view controllers presented on top of the modal host
+      // together with the host itself.
+      [viewController.presentingViewController dismissViewControllerAnimated:animated completion:completionBlock];
+    } else {
+      [viewController dismissViewControllerAnimated:animated completion:completionBlock];
+    }
   }
 }

@michalchudziak
Copy link
Contributor

Hello there 👋 this issue seems to have been inactive for the past few weeks. Because of this, it's likely that the issue is not a high priority anymore or it has been solved by OP; for these reasons, we'll close it. But please, if it's actually still an issue with 0.59.5 please comment below and we can reopen it or please send us a Pull Request with a fix 😊

sryze added a commit to sryze/react-native that referenced this issue Oct 13, 2019
sryze added a commit to sryze/react-native that referenced this issue Oct 13, 2019
sryze added a commit to sryze/react-native that referenced this issue Oct 13, 2019
sryze added a commit to sryze/react-native that referenced this issue Oct 13, 2019
sryze added a commit to sryze/react-native that referenced this issue Oct 13, 2019
sryze added a commit to sryze/react-native that referenced this issue Oct 13, 2019
Present each alert (UIAlertController) in a separate window so that they are
not affected by modals or other presented view controlelrs. This also allows
one to display mulitple alerts on top of each other (it is sometimes useful).

I basically copied a bunch of code from RCTDevLoadingView to chieve this.

This patch fixes issue facebook#22237.
@facebook facebook locked as resolved and limited conversation to collaborators Apr 25, 2020
@react-native-bot react-native-bot added the Resolution: Locked This issue was locked by the bot. label Apr 25, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants