Skip to content

Commit

Permalink
feat: add support for transparent large header on iOS (#2501)
Browse files Browse the repository at this point in the history
## Description

- requires this bug fix
#2500
- make it possible to support the stock Apple behavior where the large
header is transparent and the collapsed header is blurry with a shadow.
This is currently not possible because we inherit the blur effect from
the collapsed title, and because there's no way to set the
headerLargeTitle blur effect.

With this change, the default iOS behavior can more closely be matched
by using the following props:

```js
{
  headerLargeTitle: true,
  headerTransparent: true,
  headerBlurEffect: "systemChromeMaterial",
  headerLargeTitleShadowVisible: false,
  headerShadowVisible: true,
  headerLargeStyle: {
    // NEW: Make the large title transparent to match the background.
    backgroundColor: "transparent",
  },
}
```

Without the shadow changes, users also need to add this (and adjust for
dark mode):

```
{
  headerStyle: {
    // Hack to ensure the collapsed small header shows the shadow / border.
    backgroundColor: "rgba(255,255,255,0.01)",
  },
}
```

## Changes


### Before

This is the best we can currently do.


![IMG_5976](https://github.com/user-attachments/assets/00d2b4d0-9633-44c1-a038-c311f4e51df1)

### After


https://github.com/user-attachments/assets/b1e8999d-14ce-40ef-aef6-2478a9e6326c



<!--
Please describe things you've changed here, make a **high level**
overview, if change is simple you can omit this section.

For example:

- Updated `about.md` docs

-->

<!--

## Screenshots / GIFs




Here you can add screenshots / GIFs documenting your change.

You can add before / after section if you're changing some behavior.

-->

## Test code and steps to reproduce

<!--
Please include code that can be used to test this change and short
description how this example should work.
This snippet should be as minimal as possible and ready to be pasted
into editor (don't exclude exports or remove "not important" parts of
reproduction example)
-->

## Checklist

- [ ] Included code example that can be used to test this change
- [ ] Updated TS types
- [ ] Updated documentation: <!-- For adding new props to native-stack
-->
- [ ]
https://github.com/software-mansion/react-native-screens/blob/main/guides/GUIDE_FOR_LIBRARY_AUTHORS.md
- [ ]
https://github.com/software-mansion/react-native-screens/blob/main/native-stack/README.md
- [ ]
https://github.com/software-mansion/react-native-screens/blob/main/src/types.tsx
- [ ]
https://github.com/software-mansion/react-native-screens/blob/main/src/native-stack/types.tsx
- [ ] Ensured that CI passes
  • Loading branch information
EvanBacon authored Nov 14, 2024
1 parent 976dd89 commit 40f318a
Showing 1 changed file with 17 additions and 1 deletion.
18 changes: 17 additions & 1 deletion ios/RNSScreenStackHeaderConfig.mm
Original file line number Diff line number Diff line change
Expand Up @@ -451,8 +451,16 @@ + (UINavigationBarAppearance *)buildAppearance:(UIViewController *)vc
UINavigationBarAppearance *appearance = [UINavigationBarAppearance new];

if (config.backgroundColor && CGColorGetAlpha(config.backgroundColor.CGColor) == 0.) {
// Preserve the shadow properties in case the user wants to show the shadow on scroll.
UIColor *shadowColor = appearance.shadowColor;
UIImage *shadowImage = appearance.shadowImage;
// transparent background color
[appearance configureWithTransparentBackground];

if (!config.hideShadow) {
appearance.shadowColor = shadowColor;
appearance.shadowImage = shadowImage;
}
} else {
[appearance configureWithOpaqueBackground];
}
Expand Down Expand Up @@ -680,7 +688,15 @@ + (void)updateViewController:(UIViewController *)vc
UINavigationBarAppearance *scrollEdgeAppearance =
[[UINavigationBarAppearance alloc] initWithBarAppearance:appearance];
if (config.largeTitleBackgroundColor != nil) {
scrollEdgeAppearance.backgroundColor = config.largeTitleBackgroundColor;
// Add support for using a fully transparent bar when the backgroundColor is set to transparent.
if (CGColorGetAlpha(config.largeTitleBackgroundColor.CGColor) == 0.) {
// This will also remove the background blur effect in the large title which is otherwise inherited from the standard appearance.
[scrollEdgeAppearance configureWithTransparentBackground];
// This must be set to nil otherwise a default view will be added to the navigation bar background with an opaque background.
scrollEdgeAppearance.backgroundColor = nil;
} else {
scrollEdgeAppearance.backgroundColor = config.largeTitleBackgroundColor;
}
}
if (config.largeTitleHideShadow) {
scrollEdgeAppearance.shadowColor = nil;
Expand Down

0 comments on commit 40f318a

Please sign in to comment.