Summary:
`RCTAlertController` creates a new window, and presents itself in that window.
RCTAlertController strongly retains the window, and the window strongly retains RCTAlertController when presenting it.
This adds a new method to break that cycle once alert is dismissed.
Changelog: [Internal]
Reviewed By: shergin
Differential Revision: D25312413
fbshipit-source-id: e4048922aa697eb42c4c149827bac61bc7bc5528
Summary:
This should fix https://github.com/facebook/react-native/issues/29082 and https://github.com/facebook/react-native/issues/10471
Currently when an alert is being shown while a modal is being dismissed, it causes the alert not to show and In some cases it causes the UI to become unresponsive. I think this was caused by using RCTPresentedViewController to try and display the Alert the currently presented view. The View the Alert was going to be shown on is dismissed and the modal doesn't show. I implemented a new RCTAlertController to show the alert on top of the view, the modal being dismissed should now not interfere with the alert being shown.
## Changelog
[iOS] [Fixed] - Fixed showing Alert while closing a Modal
Pull Request resolved: https://github.com/facebook/react-native/pull/29295
Test Plan:
To recreate the bug:
1. npx react-native init Test --version 0.63.0-rc.1
2. Paste the following code into App.js
```javascript
/**
* Sample React Native App
* https://github.com/facebook/react-native
*
* format
* flow strict-local
*/
import React from 'react';
import {
SafeAreaView,
StyleSheet,
View,
Text,
StatusBar,
Modal,
Alert
} from 'react-native';
const App: () => React$Node = () => {
const [visible, setVisible] = React.useState(false)
const onShowModal = () => {
setVisible(true)
}
onCloseBroken = () => {
setVisible(false)
Alert.alert('Alert', 'Alert won\'t show')
}
onCloseWorking = () => {
setVisible(false)
setTimeout(() => Alert.alert('Alert', 'Works fine'), 10)
}
return (
<>
<StatusBar barStyle="dark-content" />
<SafeAreaView style={styles.container}>
<Text onPress={onShowModal}>Show modal</Text>
</SafeAreaView>
<Modal animationType="fade" visible={visible} onRequestClose={onCloseWorking} >
<View style={styles.container}>
<Text onPress={onCloseBroken}>Close modal immediately</Text>
<Text onPress={onCloseWorking}>Close modal with delay</Text>
</View>
</Modal>
</>
)
}
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'space-around',
},
})
export default App
```
3. cd Test && npx react-native run-ios
4. Show the modal and click the `Close modal immediately` button
The first button doesn't show the alert, the second does because it gets rendered after the modal view is dismissed. After this commit, the alert always shows on top of every view properly. You can test by pointing the react native package to my branch by modifying the package json file like this
```
"react-native": "https://github.com/devon94/react-native.git#fix-ios-modal"
```
I was unable to reproduce the case where it causes the UI to be responsive in the test app but was able to reproduce it in our react native app at work. I can provide a video later if needed but the code is too complex to simplify into a test case.
Reviewed By: sammy-SC
Differential Revision: D22783371
Pulled By: PeteTheHeat
fbshipit-source-id: 3e359645c610074ea855ee5686c59bdb9d6b696b
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/28058
I'm taking the first step towards supporting iOS 13 UIScene APIs and modernizing React Native not to assume an app only has a single window. See discussion here: https://github.com/facebook/react-native/issues/25181#issuecomment-505612941
The approach I'm taking is to take advantage of `RootTagContext` and passing it to NativeModules so that they can identify correctly which window they refer to. Here I'm just laying groundwork.
- [x] `Alert` and `ActionSheetIOS` take an optional `rootTag` argument that will cause them to appear on the correct window
- [x] `StatusBar` methods also have `rootTag` argument added, but it's not fully hooked up on the native side — this turns out to require some more work, see: https://github.com/facebook/react-native/issues/25181#issuecomment-506690818
- [x] `setNetworkActivityIndicatorVisible` is deprecated in iOS 13
- [x] `RCTPerfMonitor`, `RCTProfile` no longer assume `UIApplicationDelegate` has a `window` property (no longer the best practice) — they now just render on the key window
Next steps: Add VC-based status bar management (if I get the OK on https://github.com/facebook/react-native/issues/25181#issuecomment-506690818 ), add multiple window demo to RNTester, deprecate Dimensions in favor of a layout context, consider adding hook-based APIs for native modules such as Alert that automatically know which rootTag to pass
## Changelog
[Internal] [Changed] - Modernize Modal to use RootTagContext
[iOS] [Changed] - `Alert`, `ActionSheetIOS`, `StatusBar` methods now take an optional `surface` argument (for future iPadOS 13 support)
[iOS] [Changed] - RCTPresentedViewController now takes a nullable `window` arg
[Internal] [Changed] - Do not assume `UIApplicationDelegate` has a `window` property
Pull Request resolved: https://github.com/facebook/react-native/pull/25425
Test Plan:
- Open RNTester and:
- go to Modal and check if it still works
- Alert → see if works
- ACtionSheetIOS → see if it works
- StatusBar → see if it works
- Share → see if it works
Reviewed By: PeteTheHeat
Differential Revision: D16957751
Pulled By: hramos
fbshipit-source-id: ae2a4478e2e7f8d2be3022c9c4861561ec244a26
Summary:
**Note:** This was landed in D17722913, but reverted in D17855088. The revert had nothing to do with this NativeModule.
Changelog: [iOS][Added] Make RCTAlertManager TurboModule-compatible
Reviewed By: PeteTheHeat
Differential Revision: D17917827
fbshipit-source-id: d86ea2cddddd9535d656709296c74aebd6f45793