Skip to content

Commit

Permalink
fix(iOS): full screen modal crash on paper (#2336)
Browse files Browse the repository at this point in the history
## Description

Full screen modal was crashing sometimes on Paper.
Fixes #2317.

## Test code and steps to reproduce

Added `Test2317` to tests.

## Checklist

- [x] Included code example that can be used to test this change
- [ ] Ensured that CI passes

---------

Co-authored-by: Kacper Kafara <kacperkafara@gmail.com>
  • Loading branch information
maksg and kkafar authored Oct 4, 2024
1 parent 6502d52 commit af30489
Show file tree
Hide file tree
Showing 3 changed files with 94 additions and 0 deletions.
85 changes: 85 additions & 0 deletions apps/src/tests/Test2317.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
import * as React from 'react';
import { NavigationContainer } from '@react-navigation/native';
import { createNativeStackNavigator, NativeStackScreenProps } from '@react-navigation/native-stack';
import { DarkTheme, DefaultTheme } from '@react-navigation/native';
import { Button, StyleSheet, Text, useColorScheme } from 'react-native';
import { SafeAreaProvider, SafeAreaView } from 'react-native-safe-area-context';
import { Colors } from 'react-native/Libraries/NewAppScreen';

const Stack = createNativeStackNavigator();

const App = (): React.JSX.Element => {
const isDarkMode = useColorScheme();

return (
<SafeAreaProvider>
<NavigationContainer theme={isDarkMode ? DarkTheme : DefaultTheme}>
<Stack.Navigator>
<Stack.Screen
name="main"
component={MainScreen}
options={{ headerShown: false }}
/>
<Stack.Screen
name="modal"
component={FullScreenModal}
options={({}) => ({
presentation: 'fullScreenModal',
headerTitle: () => (
<Text style={{ color: isDarkMode ? Colors.light : Colors.dark }}>
Header Title
</Text>
)
})}
/>
</Stack.Navigator>
</NavigationContainer>
</SafeAreaProvider>
);
};

const FullScreenModal = ({ navigation }: NativeStackScreenProps<{}>) => {
const isDarkMode = useColorScheme() === 'dark';

return (
<SafeAreaView
style={[
styles.container,
{ backgroundColor: isDarkMode ? Colors.darker : Colors }
]}
>
<Text style={{ color: Colors.light }}>FullScreenModal</Text>
<Button title="Go back" onPress={navigation.goBack} />
</SafeAreaView>
);
};

const MainScreen = ({
navigation
}: NativeStackScreenProps<Record<string, object | undefined>>) => {
const isDarkMode = useColorScheme() === 'dark';

return (
<SafeAreaView
style={[
styles.container,
{ backgroundColor: isDarkMode ? Colors.darker : Colors.lighter }
]}
>
<Text style={{ color: isDarkMode ? Colors.light : Colors.dark }}>
Main Screen
</Text>
<Button title="Press" onPress={() => navigation.navigate('modal')} />
</SafeAreaView>
);
};

const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center'
}
});

export default App;
1 change: 1 addition & 0 deletions apps/src/tests/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ export { default as Test2235 } from './Test2235';
export { default as Test2252 } from './Test2252';
export { default as Test2271 } from './Test2271';
export { default as Test2282 } from './Test2282';
export { default as Test2317 } from './Test2317';
export { default as Test2332 } from './Test2332';
export { default as TestScreenAnimation } from './TestScreenAnimation';
export { default as TestHeader } from './TestHeader';
Expand Down
8 changes: 8 additions & 0 deletions ios/RNSScreenStackHeaderConfig.mm
Original file line number Diff line number Diff line change
Expand Up @@ -471,6 +471,14 @@ + (void)updateViewController:(UIViewController *)vc
UINavigationItem *navitem = vc.navigationItem;
UINavigationController *navctr = (UINavigationController *)vc.parentViewController;

// When modal is shown the underlying RNSScreen isn't attached to any navigation controller.
// During the modal dismissal transition this update method is called on this RNSScreen resulting in nil navctr.
// After the transition is completed it will be called again and will configure the navigation controller correctly.
// Also see: https://github.com/software-mansion/react-native-screens/pull/2336
if (navctr == nil) {
return;
}

NSUInteger currentIndex = [navctr.viewControllers indexOfObject:vc];
UINavigationItem *prevItem =
currentIndex > 0 ? [navctr.viewControllers objectAtIndex:currentIndex - 1].navigationItem : nil;
Expand Down

0 comments on commit af30489

Please sign in to comment.