-
Notifications
You must be signed in to change notification settings - Fork 24.5k
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
Fix disappearing alert bug on iOS #26839
Conversation
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.
This fixes it. |
React/Modules/RCTAlertManager.m
Outdated
@@ -30,6 +30,7 @@ @interface RCTAlertManager() | |||
@implementation RCTAlertManager | |||
{ | |||
NSHashTable *_alertControllers; | |||
UIWindow *_window; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should not store UIWindow
as an ivar (because it's not shared among instances of view controllers), right?
Instead, we should just remove a window instance from Screen instance on alert being dismissed. We can geet a particular window instance from presented view controller (or any mounted view) instance.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@shergin You are right, it doesn't need to be an ivar, it can be a local variable here. In that case it also must be strongly captured by the action handler block of UIAlertController, otherwise the window gets destroyed while we are showing the alert controller. It looks like UIAlertController
(or UIViewController
in general) doesn't keep a strong reference to its window.
React/Modules/RCTAlertManager.m
Outdated
UIViewController *presentingController = [UIViewController new]; | ||
self->_window.rootViewController = presentingController; | ||
self->_window.hidden = NO; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hidden
must be set to NO explicitly, otherwise the window will remain invisible
Thanks @sryze ! |
@sryze Do you know when this fix is expected to land? Are there any workarounds from the JS-side in the meantime? |
I have no idea, probably not soon. As a workaround you can create a patch for the react-native package and apply it during post-install step using patch-package. This is what I did in my project. |
@bartzy: A work around I use is to delay displaying the Alert for half a second, to make sure closing the modal has been dealt with. Ex. This is far from a legitimate approach- but this issue was blocking our app approval in iTunes and I can't easily patch react myself as I'm using Expo. In my case the Modal was to be closed immediately before the Alert appears. My work around will not work if you require to close the Modal at some arbitrary time while the Alert is visible and continues to be shown. |
An alternative to using the setTimeout is to I tried to do something like this: const handleSave = () => {
try {
setSaving(true);
await someApiRequest();
} catch(err) {
Alert.alert(err);
} finally {
setSaving(false);
}
} And instead transformed it into this: const handleSave = () => {
try {
setSaving(true);
await someApiRequest();
} catch(err) {
await new Promise(res => Alert.alert(err,null,null,{onDismiss:res}))
} finally {
setSaving(false);
}
} |
This change not work for me, may need to try another solution |
This bug still exists in RN 0.62.3 |
This PR is stale because it has been open 180 days with no activity. Remove stale label or comment or this will be closed in 7 days. |
This PR was closed because it has been stalled for 7 days with no activity. |
Summary
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 achieve this.
This patch fixes issue #22237.
My previous pull request related to this issue: #22666 (closed).
Changelog
[iOS] [Fixed] - Fixed a bug with alerts disappearing when a modal gets hidden
Test Plan
I have a test project that demonstrates the bug and allows one to verify this fix (bug no. 1 in the bug list). The project is made with React 0.61.2.