Skip to content

Commit

Permalink
fix(android): disappearing search icon on opening transparent modal (s…
Browse files Browse the repository at this point in the history
…oftware-mansion#2274)

## Description

This PR fixes disappearing search icon of the previous screen when
navigating to a transparent modal with hidden header.

When navigating to a screen with `presentation: "transparentModal"` and
`headerShown: false` the toolbar menu was
unnecessarily updated with new screen's options. The update caused the
search icon of the previous screen (still visible in the background) to
disappear.

Fixes software-mansion#2271 .

## Changes

- added `Test2271.tsx` repro
- updating the toolbar menu conditionally

## Screenshots / GIFs

### Before


https://github.com/user-attachments/assets/390f054b-b003-4b7f-b6f5-9aa9fd936dca

### After


https://github.com/user-attachments/assets/cb1fc795-c7a3-4514-9bb5-b7e1995d0b90

## Test code and steps to reproduce

- use `Test2271.tsx` for repro

## Checklist

- [x] Included code example that can be used to test this change
- [x] Ensured that CI passes
  • Loading branch information
alduzy authored and ja1ns committed Oct 9, 2024
1 parent 1f7c84c commit 679d5b6
Show file tree
Hide file tree
Showing 5 changed files with 98 additions and 10 deletions.
2 changes: 2 additions & 0 deletions android/src/main/java/com/swmansion/rnscreens/Screen.kt
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,8 @@ class Screen(
)
}

fun isTransparent(): Boolean = stackPresentation === StackPresentation.TRANSPARENT_MODAL

private fun hasWebView(viewGroup: ViewGroup): Boolean {
for (i in 0 until viewGroup.childCount) {
val child = viewGroup.getChildAt(i)
Expand Down
15 changes: 6 additions & 9 deletions android/src/main/java/com/swmansion/rnscreens/ScreenStack.kt
Original file line number Diff line number Diff line change
Expand Up @@ -97,14 +97,14 @@ class ScreenStack(
var visibleBottom: ScreenFragmentWrapper? = null // this is only set if newTop has TRANSPARENT_MODAL presentation mode
isDetachingCurrentScreen = false // we reset it so the previous value is not used by mistake
for (i in screenWrappers.indices.reversed()) {
val screen = getScreenFragmentWrapperAt(i)
if (!dismissedWrappers.contains(screen)) {
val screenWrapper = getScreenFragmentWrapperAt(i)
if (!dismissedWrappers.contains(screenWrapper)) {
if (newTop == null) {
newTop = screen
newTop = screenWrapper
} else {
visibleBottom = screen
visibleBottom = screenWrapper
}
if (!isTransparent(screen)) {
if (!screenWrapper.screen.isTransparent()) {
break
}
}
Expand Down Expand Up @@ -258,7 +258,7 @@ class ScreenStack(
private fun turnOffA11yUnderTransparentScreen(visibleBottom: ScreenFragmentWrapper?) {
if (screenWrappers.size > 1 && visibleBottom != null) {
topScreenWrapper?.let {
if (isTransparent(it)) {
if (it.screen.isTransparent()) {
val screenFragmentsBeneathTop = screenWrappers.slice(0 until screenWrappers.size - 1).asReversed()
// go from the top of the stack excluding the top screen
for (fragmentWrapper in screenFragmentsBeneathTop) {
Expand Down Expand Up @@ -363,9 +363,6 @@ class ScreenStack(
}

companion object {
private fun isTransparent(fragmentWrapper: ScreenFragmentWrapper): Boolean =
fragmentWrapper.screen.stackPresentation === Screen.StackPresentation.TRANSPARENT_MODAL

private fun needsDrawReordering(fragmentWrapper: ScreenFragmentWrapper): Boolean =
// On Android sdk 33 and above the animation is different and requires draw reordering.
// For React Native 0.70 and lower versions, `Build.VERSION_CODES.TIRAMISU` is not defined yet.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,12 @@ class ScreenStackFragment :
}

override fun onPrepareOptionsMenu(menu: Menu) {
updateToolbarMenu(menu)
// If the screen is a transparent modal with hidden header we don't want to update the toolbar
// menu because it may erase the menu of the previous screen (which is still visible in these
// circumstances). See here: https://github.com/software-mansion/react-native-screens/issues/2271
if (!screen.isTransparent() || screen.headerConfig?.isHeaderHidden == false) {
updateToolbarMenu(menu)
}
return super.onPrepareOptionsMenu(menu)
}

Expand Down
83 changes: 83 additions & 0 deletions apps/src/tests/Test2271.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
import { NavigationContainer } from '@react-navigation/native';
import {
NativeStackScreenProps,
createNativeStackNavigator,
} from '@react-navigation/native-stack';
import React from 'react';
import { Button, StyleSheet, Text, View } from 'react-native';
import { GestureHandlerRootView } from 'react-native-gesture-handler';

type StackParamList = {
Home: undefined;
Details: undefined;
};

const Stack = createNativeStackNavigator<StackParamList>();

function HomeScreen({
navigation,
}: NativeStackScreenProps<StackParamList, 'Home'>) {
return (
<View style={styles.container}>
<Text>Home Screen</Text>
<Button
title="Open Modal"
onPress={() => navigation.navigate('Details')}
/>
</View>
);
}
function DetailScreen({
navigation,
}: NativeStackScreenProps<StackParamList, 'Details'>) {
return (
<View style={styles.container}>
<Text>DetailScreen</Text>
<Button title={'Bo Back'} onPress={navigation.goBack} />
</View>
);
}

export default function App(): React.JSX.Element {
return (
<GestureHandlerRootView style={{ flex: 1 }}>
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen
options={{
headerSearchBarOptions: {
autoCapitalize: 'none',
placement: 'stacked',
hideWhenScrolling: false,
shouldShowHintSearchIcon: false,
hideNavigationBar: true,
tintColor: 'blue',
textColor: 'black',
hintTextColor: 'black',
headerIconColor: 'black',
},
}}
name="Home"
component={HomeScreen}
/>
<Stack.Screen
name="Details"
component={DetailScreen}
options={{
headerShown: false,
presentation: 'transparentModal',
}}
/>
</Stack.Navigator>
</NavigationContainer>
</GestureHandlerRootView>
);
}

const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
},
});
1 change: 1 addition & 0 deletions apps/src/tests/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -108,5 +108,6 @@ export { default as Test2231 } from './Test2231';
export { default as Test2232 } from './Test2232';
export { default as Test2235 } from './Test2235';
export { default as Test2252 } from './Test2252';
export { default as Test2271 } from './Test2271';
export { default as TestScreenAnimation } from './TestScreenAnimation';
export { default as TestHeader } from './TestHeader';

0 comments on commit 679d5b6

Please sign in to comment.