Skip to content

Commit dd6c33e

Browse files
authored
docs: add troubleshooting for blank screen when dismissing RN Modal on iOS (#370)
* chore: add rn modal in example * docs: add troubleshooting for blank screen when dismissing RN Modal on iOS
1 parent 24ccd8b commit dd6c33e

File tree

2 files changed

+83
-5
lines changed

2 files changed

+83
-5
lines changed

docs/docs/troubleshooting.mdx

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,28 @@ Related: [#354](https://github.com/lodev09/react-native-true-sheet/issues/354)
6969
A fix has been submitted to Unistyles. See [PR #1061](https://github.com/jpudysz/react-native-unistyles/pull/1061).
7070
:::
7171

72+
## Blank Screen When Dismissing React Native Modal on iOS
73+
74+
When presenting a TrueSheet on top of a React Native `<Modal>` and then dismissing the Modal (by setting `visible={false}`), the screen may go blank. This is a bug in React Native where dismissing a Modal that has another view controller presented on top of it only dismisses the topmost view controller, leaving the Modal in an inconsistent state.
75+
76+
**Workaround:**
77+
78+
Dismiss the sheet first before hiding the Modal:
79+
80+
```tsx
81+
const sheet = useRef<TrueSheet>(null)
82+
const [modalVisible, setModalVisible] = useState(false)
83+
84+
const closeModal = async () => {
85+
await sheet.current?.dismiss()
86+
setModalVisible(false)
87+
}
88+
```
89+
90+
:::info
91+
A fix has been submitted to React Native. See [PR #55005](https://github.com/facebook/react-native/pull/55005).
92+
:::
93+
7294
## Weird layout render
7395

7496
The sheet does not have control over how React Native renders components and may lead to rendering issues. To resolve this, try to minimize the use of `flex=1` in your content styles. Instead, use fixed `height` or employ `flexGrow`, `flexBasis`, etc., to manage your layout requirements.

example/shared/src/screens/ModalScreen.tsx

Lines changed: 61 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1-
import { useRef } from 'react';
2-
import { StyleSheet, Text, View } from 'react-native';
3-
import { TrueSheetProvider, type TrueSheet } from '@lodev09/react-native-true-sheet';
1+
import { useRef, useState, useEffect } from 'react';
2+
import { Modal, StyleSheet, Text, View } from 'react-native';
3+
import { TrueSheet, TrueSheetProvider } from '@lodev09/react-native-true-sheet';
44

5-
import { BLUE, GAP, LIGHT_GRAY, SPACING } from '../utils';
6-
import { Button, Input, Spacer } from '../components';
5+
import { BLUE, DARK, DARK_BLUE, DARK_GRAY, GAP, LIGHT_GRAY, SPACING } from '../utils';
6+
import { Button, DemoContent, Input, Spacer } from '../components';
77
import { PromptSheet, FlatListSheet } from '../components/sheets';
88

99
export interface ModalScreenProps {
@@ -15,6 +15,16 @@ export const ModalScreen = ({ onNavigateToTest, onDismiss }: ModalScreenProps) =
1515
const promptSheet = useRef<TrueSheet>(null);
1616
const flatlistSheet = useRef<TrueSheet>(null);
1717

18+
const [modalVisible, setModalVisible] = useState(false);
19+
const modalSimpleSheet = useRef<TrueSheet>(null);
20+
const modalFlatlistSheet = useRef<TrueSheet>(null);
21+
22+
useEffect(() => {
23+
if (modalVisible) {
24+
modalSimpleSheet.current?.present();
25+
}
26+
}, [modalVisible]);
27+
1828
return (
1929
<TrueSheetProvider>
2030
<View style={styles.content}>
@@ -28,11 +38,46 @@ export const ModalScreen = ({ onNavigateToTest, onDismiss }: ModalScreenProps) =
2838
<Button text="Dismiss Modal" onPress={onDismiss} />
2939
<Button text="TrueSheet Prompt" onPress={() => promptSheet.current?.present()} />
3040
<Button text="TrueSheet FlatList" onPress={() => flatlistSheet.current?.present()} />
41+
<Button text="Open RN Modal" onPress={() => setModalVisible(true)} />
3142
<Spacer />
3243
<Button text="Navigate Test" onPress={onNavigateToTest} />
3344

3445
<PromptSheet initialDetentIndex={0} ref={promptSheet} dimmed={false} />
3546
<FlatListSheet ref={flatlistSheet} />
47+
48+
<Modal
49+
visible={modalVisible}
50+
animationType="slide"
51+
onRequestClose={() => setModalVisible(false)}
52+
>
53+
<TrueSheetProvider>
54+
<View style={styles.modalContent}>
55+
<View style={styles.heading}>
56+
<Text style={styles.title}>React Native Modal</Text>
57+
<Text style={styles.subtitle}>
58+
This is a React Native Modal. You can present TrueSheets from here!
59+
</Text>
60+
</View>
61+
<Button text="Simple Sheet" onPress={() => modalSimpleSheet.current?.present()} />
62+
<Button text="FlatList Sheet" onPress={() => modalFlatlistSheet.current?.present()} />
63+
<Spacer />
64+
<Button text="Close Modal" onPress={() => setModalVisible(false)} />
65+
66+
<TrueSheet
67+
ref={modalSimpleSheet}
68+
detents={['auto']}
69+
// initialDetentIndex={0}
70+
dimmed={false}
71+
style={styles.simpleSheet}
72+
backgroundColor={DARK}
73+
>
74+
<DemoContent color={DARK_BLUE} text="Simple Sheet" />
75+
<Button text="Dismiss" onPress={() => modalSimpleSheet.current?.dismiss()} />
76+
</TrueSheet>
77+
<FlatListSheet ref={modalFlatlistSheet} />
78+
</View>
79+
</TrueSheetProvider>
80+
</Modal>
3681
</View>
3782
</TrueSheetProvider>
3883
);
@@ -46,6 +91,17 @@ const styles = StyleSheet.create({
4691
padding: SPACING,
4792
gap: GAP,
4893
},
94+
modalContent: {
95+
backgroundColor: DARK_GRAY,
96+
justifyContent: 'center',
97+
flex: 1,
98+
padding: SPACING,
99+
gap: GAP,
100+
},
101+
simpleSheet: {
102+
padding: SPACING,
103+
gap: GAP,
104+
},
49105
heading: {
50106
marginBottom: SPACING * 2,
51107
},

0 commit comments

Comments
 (0)