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

Navigation header looks different in ios 16 beta. #1570

Closed
dlehddnjs opened this issue Aug 23, 2022 · 26 comments · Fixed by #1579
Closed

Navigation header looks different in ios 16 beta. #1570

dlehddnjs opened this issue Aug 23, 2022 · 26 comments · Fixed by #1579
Assignees
Labels
Platform: iOS This issue is specific to iOS Repro provided A reproduction with a snack or repo is provided

Comments

@dlehddnjs
Copy link

dlehddnjs commented Aug 23, 2022

Description

Screen Shot 2022-08-23 at 10 52 25 AM

Navigation header looks different in iOS 16 Beta.
It happens in iPhone 11 Pro (16.0, 20A5349b)
I just updated iOS to 16.0 and other don't.
Is there any changes on iOS 16.0 affects to native-stack?

Expected behavior below.

Screen Shot 2022-08-23 at 10 51 51 AM

Steps to reproduce

Navigation header in all screens are looks different in iOS 15.

Snack or a link to a repository

https://snack.expo.dev/NmQgCtSUU?platform=ios

Screens version

3.5.0

React Native version

0.67.4

Platforms

iOS

JavaScript runtime

Hermes

Workflow

React Native (without Expo)

Architecture

Paper (Old Architecture)

Build type

Release mode

Device

Real device

Device model

iPhone 12 mini (But iOS version is important - 16.0 Beta)

Acknowledgements

Yes

@github-actions github-actions bot added Repro provided A reproduction with a snack or repo is provided Missing info The user didn't precise the problem enough Platform: iOS This issue is specific to iOS and removed Missing info The user didn't precise the problem enough labels Aug 23, 2022
@kkafar kkafar self-assigned this Aug 23, 2022
@kkafar
Copy link
Member

kkafar commented Aug 26, 2022

Hi @dlehddnjs,

would you mind describing the differences between iOS 15 & 16 in more verbose way? Is this only headerTitle offset, or are there more visual quirks?

image

@dlehddnjs
Copy link
Author

Hi, @kkafar,
Test results so far have not found anything other than headerTitle offset.

@notjosh
Copy link

notjosh commented Aug 31, 2022

For the title I have a repro and a fix. It's as simple as moving navitem.title = config.title; below the for (...subviews) {} loop in RNSScreenStackHeaderConfig.mm.

It looks like a bug in UIKit, where I can repro the issue in Swift as follows:

let navigationItem = viewController.navigationItem

let view = UIView(frame: .init(x: 0, y: 0, width: 60, height: 20))
view.backgroundColor = .green

// this will work:
navigationItem.titleView = view
navigationItem.title = "some title"

// this will fail:
navigationItem.title = "some title"
navigationItem.titleView = view

It seems like when a .title is added first, UIKit will add a UILabel immediately. So when we add a .titleView, autolayout bugs out resulting in layout ambiguity:

image

But if .title is added after .titleView, it doesn't update any views, so it seems to be fine.

(I didn't have a simple repro for the buttons, but I'm going to try and see if the same issue impacts them also.)

@notjosh
Copy link

notjosh commented Sep 1, 2022

I'm unable to reproduce the button on the right drifting off to the bottom. From screenshots, it seems to only occur on device, is that correct? I'm running the latest iOS 16 beta (beta8, 20A5358a).

@dlehddnjs can you confirm this is still an issue for you, and that the Snack is correct (your screenshot is a different icon, so maybe the icon(/subviews) matter).

Thanks!

@dlehddnjs
Copy link
Author

@notjosh,

Yes, I've been tested it only on device.
(Worrying about the stableness for Xcode, I did not update to Xcode beta version.)

Your solution is worked perfectly on title text, but not on Icon.
(Title is aligned perfect.)

I think size of the Icon is same, I'll figure it out whether there is un difference on icons or not.

@notjosh
Copy link

notjosh commented Sep 5, 2022

@dlehddnjs I was (finally) able to consistently reproduce problem with the icon in our app (with a semi-complicated set up), but not with the reproduction code you provided. Do you have a smaller repro that consistently causes the problem? I'm happy to look into it if you can put up a Snack that consistently triggers the issue for you!

Key points:

  • build app with Xcode 13, run app on iOS 16 (both simulator or device have the problem)
  • dynamically toggle the icon (i.e. reacting to scroll, or timer), where the initial state is hidden (i.e. headerRight: undefined)
  • title (and some other styles?) needs to be set

If all of these conditions are met, then I can get icon misalignment.

I haven't got a small repro for a Snack, as the current situation is occurring deep within in our app, and I can't easily extract it to examine/share the bug :( I also don't have a good workaround right now, but it doesn't seem to occur when building via Xcode 14...so we're hoping the bug will mostly disappear when Xcode 14/iOS 16 is released

@dlehddnjs
Copy link
Author

@notjosh,

Thank you for you help, I found where this problem occurs.
It occurs from headerRight: () => <></>
We kept reproduced this issue but other option is not affect on it.

We define NativeStackNavigationOptions and using like below.

type HeaderOption = 'default';

const DefaultNavigatorHeaderOption: NativeStackNavigationOptions = {
  // it is default header design, can override option in each screen
  headerStyle: {backgroundColor: palette.white},
  headerShadowVisible: false,
  headerBackTitleVisible: false,
  headerBackVisible: false,
  headerTintColor: palette.primaryBlack,
  headerTitleAlign: 'center',
  headerTitle: ({children}) => <SubTitle size={1}>{children}</SubTitle>,
  headerLeft: () => <></>,

  // Where problem occurs
  headerRight: () => <></>,
};

const NavigationHeaderOptions: {[key in HeaderOption]: NativeStackNavigationOptions} = {
  default: DefaultNavigatorHeaderOption,
};

export {NavigationHeaderOptions};

I think it can be occurred in headerLeft also. Is it possible?
Is there any patch about this on next version?
Or should I avoid using in code like headerRight: () => <></> ?

@hirbod
Copy link
Contributor

hirbod commented Sep 10, 2022

iOS 16 is out in two days, can we quickly land a fix for this @kkafar ?

@kkafar
Copy link
Member

kkafar commented Sep 10, 2022

@hirbod
I've tested this fix with header: #1579 (just swapping the lines around) but I had report from other @software-mansion team that it did not resolve the issue. I guess I can have it landed, as this change should not mess with any other behaviour, but it is not 100% reliant.

Edit: I haven't come up with any other fix yet, but it is something I'll work on in incoming week.

@hirbod
Copy link
Contributor

hirbod commented Sep 10, 2022

Ok, thanks for the insights. I'll pull them patch in and give it a try, but since you already have reports that's not reliant I'm not having high hopes :).

Hmu when you need testing!

@Gregoirevda
Copy link

I'm having a similar issue on iOS 16 device (not emulator). When Screen options have

<Stack.Screen options={{headerShown: false}}>

And the screen has

function onMount() {
  navigation.setOptions({headerShown: true, title: '', headerRight: <Icon name="bookmark" />})
}

The default back button misses margin left and the headerRight icon is out of the header: pushed down and right.

@hirbod
Copy link
Contributor

hirbod commented Sep 13, 2022

@Gregoirevda when is onMount triggered? useEffect? If yes, try useLayoutEffect instead. I also had this issue with iOS 15 and using useLayoutEffect was the way to fix it.

@Gregoirevda
Copy link

@hirbod It's an onCompleted of a network query. So I can't use useLayoutEffect as I need network data to set the headerRight or not

I've seen the same issue on Instagram on iOS 16: if you navigate to a user profile screen the header will look fine, but if you (close the app) and open the profile screen from an universal link (opening the link from Notes for example), they need to do a network request before knowing the person name (and adding a bell icon or not). This seem to change the order in which the header is created and the title is moved down, not aligned anymore with other icons.

I'm going to try compiling with XCode 14

@fobin
Copy link

fobin commented Sep 14, 2022

I have the same issue.
image

I'm using it like:

useLayoutEffect(() => {
    navigation.setOptions({
      headerRight: () => (
        <Icon name="ios-attach" size={30} color="white" onPress={() => {}} />
      ),
    });
  });
`

@hirbod
Copy link
Contributor

hirbod commented Sep 14, 2022

Ok, so the bug is back. @WoLewicki once implemented a fix for it

@howg0924
Copy link

@klandell
Copy link

klandell commented Sep 15, 2022

Related to this issue in react-navigation:
react-navigation/react-navigation#10840

@dlehddnjs
Copy link
Author

Related to this issue in react-navigation: react-navigation/react-navigation#10840

Following @hirbod 's answer from @klandell 's link, maybe it has fixed in later version of iOS 16.

react-navigation/react-navigation#10840 (comment)

kkafar added a commit that referenced this issue Sep 23, 2022
## Description

Potentially fixes #1570 as suggested in
[comments](#1570 (comment)).

I tested it on iOS 16.0 simulator & device - worked for me. However when
I passed this solution to other team @software-mansion, it was reported
back to me that there is no change (buggy behaviour still occurs).

I'm gonna merge this PR, as it introduces only `line-swap` change, which
should not introduce any regression and potentially fixes the bug.

**NOTE**: this issue seems to be already fixed internally by Apple as
reported
[here](react-navigation/react-navigation#10840 (comment)).

## Changes

Just moved `navitem.title = ...` assignment below `navitem.titleView =
...` one.

## Test code and steps to reproduce

See #1570

## Checklist

- [ ] Ensured that CI passes
@TheDexire
Copy link

This problem still actual
How to resolve this issue?

@stachu2k
Copy link

I have just updated to iOS 16.1 and it looks fixed :)

@arthuralee
Copy link

This issue seems to have re-emerged after ios 16.1 came out of beta. Can anyone else in here confirm this?

@chinieer
Copy link

This issue still in ios 16.1 official version

@Watersdr
Copy link

Still seeing this behavior on Xcode 14.2 iOS 16.2 iPhone 14 simulator

@fobin
Copy link

fobin commented Dec 22, 2022

@kkafar I think this should be kept open. Still seeing this with 16.2.

@fobin
Copy link

fobin commented Dec 22, 2022

I managed to find a workaround. Think issue comes from the fact I was clearing the headerTitle set in previous screen at the same time as I was bringing the headerRight element. What worked for me was to first clear the headerTitle and then in setTimeout call again navigation.setOptions and set the headerRight there separately.

@Entireno
Copy link

I am experiencing the same problem in iOS 17, both in the simulator and on the real device. Can you help to solve the problem?

mccoyplayer pushed a commit to mccoyplayer/reactScreen that referenced this issue Feb 9, 2024
## Description

Potentially fixes #1570 as suggested in
[comments](software-mansion/react-native-screens#1570 (comment)).

I tested it on iOS 16.0 simulator & device - worked for me. However when
I passed this solution to other team @software-mansion, it was reported
back to me that there is no change (buggy behaviour still occurs).

I'm gonna merge this PR, as it introduces only `line-swap` change, which
should not introduce any regression and potentially fixes the bug.

**NOTE**: this issue seems to be already fixed internally by Apple as
reported
[here](react-navigation/react-navigation#10840 (comment)).

## Changes

Just moved `navitem.title = ...` assignment below `navitem.titleView =
...` one.

## Test code and steps to reproduce

See #1570

## Checklist

- [ ] Ensured that CI passes
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Platform: iOS This issue is specific to iOS Repro provided A reproduction with a snack or repo is provided
Projects
None yet
Development

Successfully merging a pull request may close this issue.