-
-
Notifications
You must be signed in to change notification settings - Fork 575
feat(iOS): support UIBarButtonItem in header #2987
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
base: main
Are you sure you want to change the base?
feat(iOS): support UIBarButtonItem in header #2987
Conversation
4e8a7b3
to
a86dbb3
Compare
Related PR in react-navigation: react-navigation/react-navigation#12657 |
i like this |
Hey! This is really promising. We're working currently on support for iOS 26 etc. and we're doing general overhaul of the lib. As of now, we're not sure what will be the API shape & scope, therefore I won't review it for now. Once we settle the internal discussion I'll revisit your implementation. I'm sure we'll be able to land it in some form. |
I'm really glad you liked it! Yeah I saw that you have done a bunch of iOS 26 related PRs and changes to the API so I understand that my suggestion may not match the shape you are targeting. Please let me know if there are any changes I can do right now and I will happily do them asap. I truly believe something like this would be awesome for react-native-screens when iOS 26 is out of beta. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi
Great stuff. We're looking at your PR and would like to merge the changes soon. Here are some comments from me, and I believe @kkafar wants to look more closely in the following days.
Also, please update the PR with changes from main branch. There could be some conflicts.
e9b25c0
to
f53da7d
Compare
Thank you! I've updated the PR with changes from main and resolved all conflicts |
1a6bce3
to
2750468
Compare
## Description From discussion in #2987 (comment). We should rename the class into something more specific because it really does one specific thing. ## Changes title ## Test code and steps to reproduce No changes, disabling back button menu should still work. You can modify BottomTabsTest / Tab4 with `screenOption={{ headerBackButtonMenuEnabled: false }}`
Hey, I most likely won't find time tomorrow & I'm going for a two week PTO on Thursday. I'll try to review this as one of first things after I'm back from PTO. :sorry: |
ac9e6bd
to
bbcb13c
Compare
Hey! No worries! Have a nice PTO 😊 |
e2ae763
to
1bf07e5
Compare
@kmichalikk I added support for |
@kmichalikk refactored everything a bit in af27795 I realised that users might want to combine native UIBarButtonItems and React Nodes in the header left and right. So renamed |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wasn't able to properly run this probably because of some issues with linking to react-navigation PR - buttons were not displayed at all. I'll try again later. In the meantime I have two small nitpicks.
My bad! I forgot to push my latest commits to react-navigation. Should be working now |
4c250ef
to
683264d
Compare
683264d
to
562e893
Compare
@kmichalikk I added support for ![]() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good 👍
Some nitpick & suggestions below.
I pulled the PR locally and merged main, works fine but found some visual bugs that I suspect are native, but haven't checked that yet.
ios/RNSBarButtonItem.mm
Outdated
#if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && defined(__IPHONE_26_0) && \ | ||
__IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_26_0 | ||
if (@available(iOS 26.0, *)) { | ||
self.style = UIBarButtonItemStyleProminent; | ||
} | ||
#endif |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For iOS < 26 there is no style set explicitly here; maybe, to be consistent, we should set it to something? And please mention the difference for iOS versions somewhere in the docs.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think we need to set it to something else on iOS < 26. I believe it's better to leave it untouched and use the default style of the OS when the prominent style is not available. UIBarButtonItemStylePlain
is the default style of iOS < 26.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And about docs, I'm linking to the Apple docs in the JSDoc comments in the type declaration. I'm also mentioning that "Prominent" is only available on iOS 26. https://github.com/johankasperi/react-navigation/blob/668b77545440c51f473bf7e392a6b8b946eec8f9/packages/native-stack/src/types.tsx#L729
Could you point me to where in the docs I should also mention this?
One could also argue that linking to the iOS docs is sufficient, especially during the beta period when stuff might be changed by Apple, since by trying to copy Apples docs to the React Native Screen docs the RNS docs might become dated quickly when Apple are doing changes. But I'm not gonna be the judge of that 😊
@@ -0,0 +1,412 @@ | |||
// NOTE: The full native feature set (style, image, menu, etc.) is available, but the TS types in src/types.tsx need to be updated to match. This example uses only the currently typed props (title, icon, onPress, enabled). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In this case we should add some documentation to src/types.tsx, maybe also to GUIDE_FOR_LIBRARY_AUTHORS, especially the different cases when the behavior is different for iOS 26 vs 18. I saw there is more documentation in the PR for react-navigation, but it would be nice to have it also here in screens.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you mean this interface?
react-native-screens/src/types.tsx
Line 545 in 5abbab3
export interface ScreenStackHeaderConfigProps extends ViewProps { |
And in GUIDE_FOR_LIBRARY_AUTHORS, do you mean I should add it under this section? https://github.com/software-mansion/react-native-screens/blob/main/guides/GUIDE_FOR_LIBRARY_AUTHORS.md#screenstackheaderconfig
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's what I was thinking about, It'd be good to have something in the same place where other screens components' props are defined for quick reference when someone new jumps in. IN GUIDE... there is this section "Below is a list of properties that can be set with ScreenStackHeaderConfig
component:" and since you are adding new props, we should keep it in sync & write something there. Same for src/types.tsx
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thansk for pointing me to where I should write something. I will do that asap
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added the types in this commit 3e2f63d
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added docs in this commit b41acf8
9cd5ae8
to
6cda9e9
Compare
03ed736
to
49fb1b8
Compare
I tested this and it seems to fix several UI issues on iOS 26. Thank you @johankasperi ! 🙏 @kkafar @kmichalikk is there any chance this might be released in the next few days? 😇 |
Thank you! Don't know your circumstances for the deadline but wanted to share that you can opt out from the new design with UIDesignRequiresCompatibility in your Info.plist |
Apple is considering our App for featuring. So, opting out is no an option for us. :/ |
I understand. Congrats for being considered for featuring! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Again, great job. I left a comment about the docs, nothing else from me.
I wanna update you, that I'm starting to look at this PR 😅 I can't say however we'll be able to land in in just couple of days, since it's a bit chunky. Remember that you always have |
Description
The current implementation of
headerLeft
andheaderRight
adds a react view as a custom view in a UIBarButtonItem. This implementation is sufficient at most times but I believe we can achieve greater "native feel" if the native stack has an protocol for adding actual UIBarButtonItems in the header. As the UIBarButtonItems has properties and features that can be difficult to mimic with a react view.Also with the introduction of iOS 26, using only custom views in UIBarButtonItem presents some limitations. Mainly that the adaptive tint color (based on the underlying view) is not working on a UIBarButtonItem with a custom view as demonstrated below under "Screenshots".
Changes
This PR adds the properties
headerRightItems
andheaderLeftItems
on the native stack Screen that makes it possible to add one or several UIBarButtonItem to the right/left of the header and/or functions returning a React Node. Most of the features of the UIBarButtonItem is supported (see either "Bar Button Items" in the example apps or the type definition).Screenshots / GIFs
Non adaptive tint color when using old property
headerRight
on iOS 26Simulator.Screen.Recording.-.iPhone.16.Pro.-.2025-06-27.at.16.31.10.mov
Adaptive tint color when using new property
headerRightBarButtonItems
on iOS 26Simulator.Screen.Recording.-.iPhone.16.Pro.-.2025-06-27.at.16.28.30.mov
UIBarButtonItem with style "prominent" on iOS 26
UIBarButtonItem with UIMenu on iOS 26
Simulator.Screen.Recording.-.iPhone.16.Pro.-.2025-06-27.at.16.29.02.mov
Test code and steps to reproduce
I've created a screen named "Bar Button Items" in the example app that showcases all of the proposed features.
Checklist
Unsure if I need to do this. I'm targeting react-navigation v6 and above so no JS changes has been made to react-native-screens in this PR. Would appreciate some guidance to if and where I should make documentation changes if needed. Thank you!