Skip to content

Commit

Permalink
fix(iOS): header left and right layout on fabric (software-mansion#2248)
Browse files Browse the repository at this point in the history
## Description

This PR fixes the header layout mismatch when updating both `headerLeft`
and `headerRight` options simultaneously using `navigation.setOptions`.

Fixes software-mansion#2231 .

## Changes

- Forced subview to re-layout when updating layoutMetrics
- added `Test2231.tsx` repro


## Screenshots / GIFs

### Before
![Screenshot 2024-07-16 at 12 05
14](https://github.com/user-attachments/assets/37a5a77d-1cd5-457f-901e-9dd5b4065a8f)

### After
![Screenshot 2024-07-16 at 12 04
49](https://github.com/user-attachments/assets/025db807-ef6d-46f2-b4c0-cd9f06e03d93)

## Test code and steps to reproduce

- Use `Test2231.tsx` repro

## Checklist

- [x] Ensured that CI passes
  • Loading branch information
alduzy authored and ja1ns committed Oct 9, 2024
1 parent f005556 commit 4546d0c
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 0 deletions.
56 changes: 56 additions & 0 deletions apps/src/tests/Test2231.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import { createNativeStackNavigator } from '@react-navigation/native-stack';
import React, { useLayoutEffect, useState } from 'react';
import { View } from 'react-native';

import { SettingsSwitch, Square } from '../shared';
import { NavigationContainer } from '@react-navigation/native';

const SettingsScreen = ({ navigation }: any) => {
const [hasLeftItem, setHasLeftItem] = useState(false);

const square1 = (props: { tintColor?: string }) => (
<View style={{ gap: 8, flexDirection: 'row' }}>
{hasLeftItem && <Square {...props} color="green" size={20} />}
<Square {...props} color="green" size={20} />
</View>
);

const square2 = (props: { tintColor?: string }) => (
<Square {...props} color="red" size={20} />
);

useLayoutEffect(() => {
navigation.setOptions({
headerRight: square1,
headerTitle: undefined,
headerLeft: hasLeftItem ? square2 : undefined,
headerBackTitleVisible: false,
});
}, [navigation, hasLeftItem]);

return (
<SettingsSwitch
label="Left item"
value={hasLeftItem}
onValueChange={setHasLeftItem}
/>
);
};

const Stack = createNativeStackNavigator();

const App = () => (
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen
name="Settings"
component={SettingsScreen}
options={{
headerTintColor: 'hotpink',
}}
/>
</Stack.Navigator>
</NavigationContainer>
);

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 @@ -104,5 +104,6 @@ export { default as Test2184 } from './Test2184';
export { default as Test2223 } from './Test2223';
export { default as Test2227 } from './Test2227';
export { default as Test2229 } from './Test2229';
export { default as Test2231 } from './Test2231';
export { default as TestScreenAnimation } from './TestScreenAnimation';
export { default as TestHeader } from './TestHeader';
3 changes: 3 additions & 0 deletions ios/RNSScreenStackHeaderSubview.mm
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,9 @@ - (void)updateLayoutMetrics:(const react::LayoutMetrics &)layoutMetrics
self);
} else {
self.bounds = CGRect{CGPointZero, frame.size};
// We're forcing the parent view to layout this subview with correct frame size,
// see: https://github.com/software-mansion/react-native-screens/pull/2248
[self.superview layoutIfNeeded];
}
}

Expand Down

0 comments on commit 4546d0c

Please sign in to comment.