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

fix(iOS): fullscreenmodal color scheme adaptability #2211

Merged
merged 12 commits into from
Jun 26, 2024
1 change: 1 addition & 0 deletions apps/test-examples/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ import Test1844 from './src/Test1844';
import Test1864 from './src/Test1864';
import Test1970 from './src/Test1970';
import Test1981 from './src/Test1981';
import Test2002 from './src/Test2002';
import Test2008 from './src/Test2008';
import Test2028 from './src/Test2028';
import Test2048 from './src/Test2048';
Expand Down
59 changes: 59 additions & 0 deletions apps/test-examples/src/Test2002.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import * as React from 'react';
import { View, Button, useColorScheme, StyleSheet } from 'react-native';
import {
DarkTheme,
DefaultTheme,
NavigationContainer,
} from '@react-navigation/native';
import { createNativeStackNavigator } from '@react-navigation/native-stack';

function HomeScreen({ navigation }) {
return (
<View style={styles.container}>
<Button
onPress={() => navigation.navigate('fullScreenModal')}
title="Open fullScreenModal"
/>
<Button
onPress={() => navigation.navigate('formSheet')}
title="Open formSheet"
/>
</View>
);
}

function ModalScreen({ navigation }) {
return (
<View style={styles.container}>
<Button onPress={() => navigation.goBack()} title="Dismiss" />
</View>
);
}

const RootStack = createNativeStackNavigator();

export default function App() {
const scheme = useColorScheme();

return (
<NavigationContainer theme={scheme === 'dark' ? DarkTheme : DefaultTheme}>
<RootStack.Navigator>
<RootStack.Screen name="Home" component={HomeScreen} />
<RootStack.Screen
name="formSheet"
component={ModalScreen}
options={{ presentation: 'formSheet' }}
/>
<RootStack.Screen
name="fullScreenModal"
component={ModalScreen}
options={{ presentation: 'fullScreenModal' }}
/>
</RootStack.Navigator>
</NavigationContainer>
);
}

const styles = StyleSheet.create({
container: { flex: 1, alignItems: 'center', justifyContent: 'center' },
});
22 changes: 22 additions & 0 deletions ios/RNSModalScreen.mm
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,28 @@

@implementation RNSModalScreen

// When using UIModalPresentationStyleFullScreen the whole view hierarchy mounted under primary `UITransitionView` is
// removed, including React's root view, which observes for trait collection changes & sends it to `Appearance` module
// via system notification centre. To workaround this detached-root-view-situation we emit the event to React's
// `Appearance` module ourselves. For the RCTRootView observer, visit
// https://github.com/facebook/react-native/blob/d3e0430deac573fd44792e6005d5de20e9ad2797/packages/react-native/React/Base/RCTRootView.m#L362
// For more information, see https://github.com/software-mansion/react-native-screens/pull/2211.
- (void)traitCollectionDidChange:(UITraitCollection *)previousTraitCollection
{
[super traitCollectionDidChange:previousTraitCollection];
if (RCTSharedApplication().applicationState == UIApplicationStateBackground ||
self.stackPresentation != RNSScreenStackPresentationFullScreenModal) {
return;
}

[[NSNotificationCenter defaultCenter]
postNotificationName:RCTUserInterfaceStyleDidChangeNotification
object:self
userInfo:@{
RCTUserInterfaceStyleDidChangeNotificationTraitCollectionKey : self.traitCollection,
}];
}

#ifdef RCT_NEW_ARCH_ENABLED
+ (react::ComponentDescriptorProvider)componentDescriptorProvider
{
Expand Down
Loading