-
-
Notifications
You must be signed in to change notification settings - Fork 537
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
iOS back button/menu title always is "back" when headerShown is false #1864
Comments
Thanks for reporting, I can confirm the issue, will look into it. |
Hey @h-five-e, would you mind trying fix from #1866? To test the fix you can install screens directly from branch in your "react-native-screens": "software-mansion/react-native-screens#@kkafar/bad-text-on-back-button" |
Oh wow, that's really quick! That does indeed fix it 🙏🏻 thank you! I do run into a semi-related issue. If, say, screen C uses a |
I do not consider it a bug. IIRC |
Cool, thanks for the feedback. We use it to provide a "back" text in cases where the title is a bit long (related to #1589), so we're keeping our fingers crossed on a fix there although that seems a little more involved 😅. Anyway this particular issue seems to be resolved, thank you |
It looks like #1589 was already fixed in native stack v6 Does this still happen there? My follow up question would be: do you import |
I did a quick check, I'm using I cannot check back in until Monday, if necessary I can work on a repro then/Tuesday (and open a new report). I hope you have an enjoyable weekend! |
So according to react-navigation/react-navigation#10844 that issue should be fixed. In case it is still present - let me know. |
#1866) ## Description Ah, here we go again... When header is hidden (`headerShown: false` in v6, `hidden: true` in v5) the method that updates header configuration returns early just after setting some layout related and LTR/RTL options, thus `title` property of current `UINavigationItem` is left unset leading to system default name `Back` being displayed in "back context menu". Fixes #1864 ## Changes When returning early (because header is hidden) we now set the `UINavigationItem` property to proper value. ## Test code and steps to reproduce `Test1864` in `FabricTestExample` & `TestsExample`. I've also tested it in context of * #1646 and mix of both. Seems to work fine. ## Checklist - [x] Included code example that can be used to test this change - [x] Ensured that CI passes
It seems to be a regression in |
## Description ~This PR improves upon #2105. #2105 allowed to use iOS 14 default back button behavior when label is not provided. This PR allows to modify the behavior by allowing to provide UINavigationButtonBackButtonDisplayMode and enables it for custom text (without style modifications). The main problem is that we used to provide backButtonItem in most of the cases which [disables](https://developer.apple.com/documentation/uikit/uinavigationitem/3656350-backbuttondisplaymode) backButtonDisplayMode.~ This PR adds possibility to customize default behavior of back button using `backButtonDisplayMode` ([UINavigationBackButtonDisplayMode](https://developer.apple.com/documentation/uikit/uinavigationitem/backbuttondisplaymode)) for iOS. :warning: **This modifies only default back button**, when any customization is added (including headerBackTitle) in native part we create custom `RNSUIBarButtonItem` and set it as `backButtonItem`, which [disables](https://developer.apple.com/documentation/uikit/uinavigationitem/3656350-backbuttondisplaymode) `backButtonDisplayMode` behavior. I tried to make it work together with custom label (`headerBackTitle`) using `prevItem.backButtonTitle`, but due to iOS limitations it is not viable option. It influences also back button menu - changes the label of previous screen - which is not the behavior we want. To sum up, `backButtonDisplayMode` work when none of: - `headerBackTitleStyle.fontFamily` - `headerBackTitleStyle.fontSize` - `headerBackTitle` - `disableBackButtonMenu` are set. ## Screenshots / GIFs |Paper|Fabric| |-|-| |<video src="https://github.com/software-mansion/react-native-screens/assets/11800297/c6aa7697-4331-4cb4-a81d-7f77f128513d" />|<video src="https://github.com/software-mansion/react-native-screens/assets/11800297/fa0edd92-1aa2-45e5-a466-516c0ec120d2" />| <details> <summary>Example component used in tests:</summary> ```jsx import * as React from 'react'; import { Button, View, Text, StyleSheet } from 'react-native'; import { NavigationContainer, ParamListBase } from '@react-navigation/native'; import { createNativeStackNavigator } from '@react-navigation/native-stack'; import { NativeStackNavigationProp } from '@react-navigation/native-stack'; const Stack = createNativeStackNavigator(); type NavProp = { navigation: NativeStackNavigationProp<ParamListBase>; }; export default function App() { return ( <NavigationContainer> <Stack.Navigator> <Stack.Screen name="screenA" component={ScreenA} options={{ headerTitle: 'A: Home' }} /> <Stack.Screen name="screenB" component={ScreenB} options={{ headerTitle: 'B: default', backButtonDisplayMode: 'default', }} /> <Stack.Screen name="screenC" component={ScreenC} options={{ headerTitle: 'C: generic', backButtonDisplayMode: 'generic', }} /> <Stack.Screen name="screenD" component={ScreenD} options={{ headerTitle: 'D: minimal', backButtonDisplayMode: 'minimal', }} /> <Stack.Screen name="screenE" component={ScreenE} options={{ headerTitle: 'E: custom', headerBackTitle: 'Back Title', backButtonDisplayMode: 'minimal', }} /> </Stack.Navigator> </NavigationContainer> ); } const ScreenA = ({ navigation }: NavProp) => ( <View style={styles.container}> <Text>Screen A</Text> <Button onPress={() => navigation.navigate('screenB')} title="Go to screen B" /> </View> ); const ScreenB = ({ navigation }: NavProp) => ( <View style={styles.container}> <Text>Screen B</Text> <Text>backButtonDisplayMode: default</Text> <Button onPress={() => navigation.navigate('screenC')} title="Go to screen C" /> </View> ); const ScreenC = ({ navigation }: NavProp) => ( <View style={{ flex: 1, paddingTop: 50 }}> <Text>Screen C</Text> <Text>backButtonDisplayMode: generic</Text> <Button onPress={() => navigation.navigate('screenD')} title="Go to screen D" /> </View> ); const ScreenD = ({ navigation }: NavProp) => ( <View style={styles.container}> <Text>Screen D</Text> <Text>backButtonDisplayMode: minimal</Text> <Button onPress={() => navigation.navigate('screenE')} title="Go to screen E" /> </View> ); const ScreenE = (_props: NavProp) => ( <View style={styles.container}> <Text>Screen E</Text> <Text>backButtonDisplayMode omitted because of the headerBackTitle</Text> </View> ); const styles = StyleSheet.create({ container: { flex: 1, alignItems: 'center', justifyContent: 'space-around' }, }); ``` </details> ## Checklist - [x] Included code example that can be used to test this change - [x] Updated TS types - [x] Updated documentation: <!-- For adding new props to native-stack --> - [x] https://github.com/software-mansion/react-native-screens/blob/main/guides/GUIDE_FOR_LIBRARY_AUTHORS.md - [x] https://github.com/software-mansion/react-native-screens/blob/main/native-stack/README.md - [x] https://github.com/software-mansion/react-native-screens/blob/main/src/types.tsx - [x] https://github.com/software-mansion/react-native-screens/blob/main/src/native-stack/types.tsx - [x] Ensured that CI passes Tested #1864: Paper ✅ Fabric ✅ Tested #1646: Paper ❌ Fabric ❌ - but it does not work on main too, could now be achieved using `backButtonDisplayMode: ‘minimal’` --------- Co-authored-by: Kacper Kafara <kacper.kafara@swmansion.com>
software-mansion#1866) ## Description Ah, here we go again... When header is hidden (`headerShown: false` in v6, `hidden: true` in v5) the method that updates header configuration returns early just after setting some layout related and LTR/RTL options, thus `title` property of current `UINavigationItem` is left unset leading to system default name `Back` being displayed in "back context menu". Fixes software-mansion#1864 ## Changes When returning early (because header is hidden) we now set the `UINavigationItem` property to proper value. ## Test code and steps to reproduce `Test1864` in `FabricTestExample` & `TestsExample`. I've also tested it in context of * software-mansion#1646 and mix of both. Seems to work fine. ## Checklist - [x] Included code example that can be used to test this change - [x] Ensured that CI passes
…e-mansion#2123) ## Description ~This PR improves upon software-mansion#2105. software-mansion#2105 allowed to use iOS 14 default back button behavior when label is not provided. This PR allows to modify the behavior by allowing to provide UINavigationButtonBackButtonDisplayMode and enables it for custom text (without style modifications). The main problem is that we used to provide backButtonItem in most of the cases which [disables](https://developer.apple.com/documentation/uikit/uinavigationitem/3656350-backbuttondisplaymode) backButtonDisplayMode.~ This PR adds possibility to customize default behavior of back button using `backButtonDisplayMode` ([UINavigationBackButtonDisplayMode](https://developer.apple.com/documentation/uikit/uinavigationitem/backbuttondisplaymode)) for iOS. :warning: **This modifies only default back button**, when any customization is added (including headerBackTitle) in native part we create custom `RNSUIBarButtonItem` and set it as `backButtonItem`, which [disables](https://developer.apple.com/documentation/uikit/uinavigationitem/3656350-backbuttondisplaymode) `backButtonDisplayMode` behavior. I tried to make it work together with custom label (`headerBackTitle`) using `prevItem.backButtonTitle`, but due to iOS limitations it is not viable option. It influences also back button menu - changes the label of previous screen - which is not the behavior we want. To sum up, `backButtonDisplayMode` work when none of: - `headerBackTitleStyle.fontFamily` - `headerBackTitleStyle.fontSize` - `headerBackTitle` - `disableBackButtonMenu` are set. ## Screenshots / GIFs |Paper|Fabric| |-|-| |<video src="https://github.com/software-mansion/react-native-screens/assets/11800297/c6aa7697-4331-4cb4-a81d-7f77f128513d" />|<video src="https://github.com/software-mansion/react-native-screens/assets/11800297/fa0edd92-1aa2-45e5-a466-516c0ec120d2" />| <details> <summary>Example component used in tests:</summary> ```jsx import * as React from 'react'; import { Button, View, Text, StyleSheet } from 'react-native'; import { NavigationContainer, ParamListBase } from '@react-navigation/native'; import { createNativeStackNavigator } from '@react-navigation/native-stack'; import { NativeStackNavigationProp } from '@react-navigation/native-stack'; const Stack = createNativeStackNavigator(); type NavProp = { navigation: NativeStackNavigationProp<ParamListBase>; }; export default function App() { return ( <NavigationContainer> <Stack.Navigator> <Stack.Screen name="screenA" component={ScreenA} options={{ headerTitle: 'A: Home' }} /> <Stack.Screen name="screenB" component={ScreenB} options={{ headerTitle: 'B: default', backButtonDisplayMode: 'default', }} /> <Stack.Screen name="screenC" component={ScreenC} options={{ headerTitle: 'C: generic', backButtonDisplayMode: 'generic', }} /> <Stack.Screen name="screenD" component={ScreenD} options={{ headerTitle: 'D: minimal', backButtonDisplayMode: 'minimal', }} /> <Stack.Screen name="screenE" component={ScreenE} options={{ headerTitle: 'E: custom', headerBackTitle: 'Back Title', backButtonDisplayMode: 'minimal', }} /> </Stack.Navigator> </NavigationContainer> ); } const ScreenA = ({ navigation }: NavProp) => ( <View style={styles.container}> <Text>Screen A</Text> <Button onPress={() => navigation.navigate('screenB')} title="Go to screen B" /> </View> ); const ScreenB = ({ navigation }: NavProp) => ( <View style={styles.container}> <Text>Screen B</Text> <Text>backButtonDisplayMode: default</Text> <Button onPress={() => navigation.navigate('screenC')} title="Go to screen C" /> </View> ); const ScreenC = ({ navigation }: NavProp) => ( <View style={{ flex: 1, paddingTop: 50 }}> <Text>Screen C</Text> <Text>backButtonDisplayMode: generic</Text> <Button onPress={() => navigation.navigate('screenD')} title="Go to screen D" /> </View> ); const ScreenD = ({ navigation }: NavProp) => ( <View style={styles.container}> <Text>Screen D</Text> <Text>backButtonDisplayMode: minimal</Text> <Button onPress={() => navigation.navigate('screenE')} title="Go to screen E" /> </View> ); const ScreenE = (_props: NavProp) => ( <View style={styles.container}> <Text>Screen E</Text> <Text>backButtonDisplayMode omitted because of the headerBackTitle</Text> </View> ); const styles = StyleSheet.create({ container: { flex: 1, alignItems: 'center', justifyContent: 'space-around' }, }); ``` </details> ## Checklist - [x] Included code example that can be used to test this change - [x] Updated TS types - [x] Updated documentation: <!-- For adding new props to native-stack --> - [x] https://github.com/software-mansion/react-native-screens/blob/main/guides/GUIDE_FOR_LIBRARY_AUTHORS.md - [x] https://github.com/software-mansion/react-native-screens/blob/main/native-stack/README.md - [x] https://github.com/software-mansion/react-native-screens/blob/main/src/types.tsx - [x] https://github.com/software-mansion/react-native-screens/blob/main/src/native-stack/types.tsx - [x] Ensured that CI passes Tested software-mansion#1864: Paper ✅ Fabric ✅ Tested software-mansion#1646: Paper ❌ Fabric ❌ - but it does not work on main too, could now be achieved using `backButtonDisplayMode: ‘minimal’` --------- Co-authored-by: Kacper Kafara <kacper.kafara@swmansion.com>
Description
If you have a stack of screens, the back button and the back button menu show the title of the previous screen, except when the header of the previous screen is not shown, in which case the shown title will revert to "back" (or localised equivalent).
For example:
The names of
screenA
andscreenC
will beback
where as the others will showscreen x title
. I expect this to bescreen x title
for all screens, regardless of whether or not the header has been shown.I have provided a snack. I am not quite familiar with Expo and Snacks and the versions differ a little from my app (for example I am using react native 0.71.7 and react-native-screens 3.24 locally, which are newer) but it has the same issue on the newer versions.
Steps to reproduce
headerShown
isfalse
and another screen to navigate to from thereSnack or a link to a repository
https://snack.expo.dev/@hanneke/navigation-ios-back-name-not-properly-set-repro
Screens version
3.20.0
React Native version
0.71.3
Platforms
iOS
JavaScript runtime
Hermes
Workflow
React Native (without Expo)
Architecture
Paper (Old Architecture)
Build type
Debug mode
Device
Real device
Device model
iPhone 11 16.5.1
Acknowledgements
Yes
The text was updated successfully, but these errors were encountered: