Skip to content

Conversation

t0maboro
Copy link
Contributor

@t0maboro t0maboro commented Sep 10, 2025

Description

Closes: https://github.com/software-mansion/react-native-screens-labs/issues/352

Should be reviewed/merged after #2987 - as for now, moving to draft.

Problem definition

On iOS 26, when headerTitle is a component containing text that overflows its parent container, the text is not correctly truncated. Instead, part of it is displayed underneath the right header button.

Root cause analysis

After the changes introduced in iOS 26, our current method of calculating edgeInsets, which are based on the sum of the UINavigationBar.directionalLayoutMargins and its content directionalLayoutMargins is insufficient. The problem also lies in the fact that by calculating insets only based on these components, we lack full information about the positions of the buttons within the navigation bar. These insets are approximate, which may lead to a gap between the left/right buttons and the title component.

old-insets

Solution

With a flexbox-based model, a better approach would be to imagine that all React components are wrapped in a single component in which they're layouting in a flex manner. This way, the layout of all HeaderSubviews can be fully delegated to Yoga. This is achievable by reading the left edge of the ScreenStackHeaderLeftView and the right edge of the ScreenStackHeaderRightView. In the current model, this allows Yoga to operate in the area:

<ScreenStackHeaderConfig >
  <ScreenStackHeaderLeftView />
  <ScreenStackHeaderCenterView />
  <ScreenStackHeaderRightView />
<ScreenStackHeaderConfig />

This enables the text to stretch across the full available width, either if flex: 1 is provided or if the text is long enough to require truncating.

new-insets

Known issues

  1. This approach for calculating insets requires a fully computed layout in the UINavigationBar. Therefore, during transitions, a correct update may not occur. Detection of the proper moment when update should come is problematic, what is resulting in content jumping during forward navigation. However, once the transition completes, the header stabilizes. This issue only affects headers where components do not have a fixed width.

  2. A new feature — support for UIBarButtonItem is causing layout issues because if a button is native, from Yoga’s perspective, it should be ignored for layout. For example, if there is one native button on both the left and right sides, we should take insets based on the right edge of headerLeftItems and the left edge of headerRightItems. Additionally, we need to clearly define whether we allow mixing of React components and native components in header[Left/Right]Items props.

Testing coverage

  • All TCs from the sheet
  • BackTitle and BackButton support
  • RTL support
  • Multiple left & right (UIBarButtonItem) buttons support

Changes

  • added a new algorithm for calculating the space for React components in header
  • hidden new implementation only to work with iOS 26+ to prevent any regression with older version
  • added overflow: hidden to mitigate jumping content on the push transition issue

Screenshots / GIFs

Before

legacy.mov

After

modern.mov

Test code and steps to reproduce

I believe that this may require more integration testing with other APIs in the future; therefore, I added a new example that will collect all new TC we should cover (e.g., support for UIBarButtonItems soon).

Checklist

  • Included code example that can be used to test this change
  • Ensured that CI passes

Further steps

For this PR, I need to create follow-up tickets for taking further actions:

@t0maboro t0maboro marked this pull request as ready for review September 15, 2025 08:38
@t0maboro t0maboro changed the title WIP: POC - new impl for calculating edgeInsets feat(iOS, Stack): New implementation for calculating edgeInsets Sep 15, 2025
@t0maboro t0maboro marked this pull request as draft September 15, 2025 09:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant