Skip to content

feat(iOS): Implement blurEffect for new architecture #2207

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

Merged
merged 4 commits into from
Aug 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -296,4 +296,11 @@ class ScreenStackHeaderConfigViewManager :
) {
logNotAvailable("backButtonDisplayMode")
}

override fun setBlurEffect(
view: ScreenStackHeaderConfig?,
value: String?,
) {
logNotAvailable("blurEffect")
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,9 @@ public void setProperty(T view, String propName, @Nullable Object value) {
case "backButtonInCustomView":
mViewManager.setBackButtonInCustomView(view, value == null ? false : (boolean) value);
break;
case "blurEffect":
mViewManager.setBlurEffect(view, (String) value);
break;
case "topInsetEnabled":
mViewManager.setTopInsetEnabled(view, value == null ? false : (boolean) value);
break;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,5 +39,6 @@ public interface RNSScreenStackHeaderConfigManagerInterface<T extends View> {
void setBackButtonDisplayMode(T view, @Nullable String value);
void setHideBackButton(T view, boolean value);
void setBackButtonInCustomView(T view, boolean value);
void setBlurEffect(T view, @Nullable String value);
void setTopInsetEnabled(T view, boolean value);
}
32 changes: 32 additions & 0 deletions apps/src/screens/HeaderOptions.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import {
ToastProvider,
useToast,
} from '../shared';
import { BlurEffectTypes } from 'react-native-screens';

type StackParamList = {
Main: undefined;
Expand Down Expand Up @@ -62,6 +63,8 @@ const SettingsScreen = ({
const [headerBackTitle, setHeaderBackTitle] = useState('Back');
const [headerShadowVisible, setHeaderShadowVisible] = useState(false);
const [headerTransparent, setHeaderTransparent] = useState(false);
const [headerBlurEffect, setHeaderBlurEffect] =
useState<BlurEffectTypes>('extraLight');

const square = (props: { tintColor?: string }) => (
<Square {...props} color="green" size={20} />
Expand All @@ -80,6 +83,7 @@ const SettingsScreen = ({
headerLeft: headerItem === 'left' ? square : undefined,
headerShadowVisible,
headerTransparent,
headerBlurEffect,
});
}, [
navigation,
Expand All @@ -92,6 +96,7 @@ const SettingsScreen = ({
headerShown,
headerShadowVisible,
headerTransparent,
headerBlurEffect,
]);

return (
Expand Down Expand Up @@ -170,6 +175,33 @@ const SettingsScreen = ({
value={headerBackTitle}
onValueChange={setHeaderBackTitle}
/>
<SettingsPicker<BlurEffectTypes>
label="Header blur effect"
value={headerBlurEffect}
items={[
'extraLight',
'light',
'dark',
'regular',
'prominent',
'systemUltraThinMaterial',
'systemThinMaterial',
'systemMaterial',
'systemThickMaterial',
'systemChromeMaterial',
'systemUltraThinMaterialLight',
'systemThinMaterialLight',
'systemMaterialLight',
'systemThickMaterialLight',
'systemChromeMaterialLight',
'systemUltraThinMaterialDark',
'systemThinMaterialDark',
'systemMaterialDark',
'systemThickMaterialDark',
'systemChromeMaterialDark',
]}
onValueChange={setHeaderBlurEffect}
/>
<Button title="Go back" onPress={() => navigation.goBack()} />
</ScrollView>
);
Expand Down
2 changes: 2 additions & 0 deletions ios/RNSConvert.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ namespace react = facebook::react;

+ (RNSSearchBarPlacement)RNSScreenSearchBarPlacementFromCppEquivalent:(react::RNSSearchBarPlacement)placement;

+ (UIBlurEffectStyle)UIBlurEffectStyleFromCppEquivalent:(react::RNSScreenStackHeaderConfigBlurEffect)blurEffect;

@end

#endif // RCT_NEW_ARCH_ENABLED
65 changes: 65 additions & 0 deletions ios/RNSConvert.mm
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,71 @@ + (RNSSearchBarPlacement)RNSScreenSearchBarPlacementFromCppEquivalent:(react::RN
}
}

+ (UIBlurEffectStyle)UIBlurEffectStyleFromCppEquivalent:(react::RNSScreenStackHeaderConfigBlurEffect)blurEffect
{
#if !TARGET_OS_TV && defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && defined(__IPHONE_13_0) && \
__IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_13_0
if (@available(iOS 13.0, *)) {
switch (blurEffect) {
case react::RNSScreenStackHeaderConfigBlurEffect::ExtraLight:
return UIBlurEffectStyleExtraLight;
case react::RNSScreenStackHeaderConfigBlurEffect::Light:
return UIBlurEffectStyleLight;
case react::RNSScreenStackHeaderConfigBlurEffect::Dark:
return UIBlurEffectStyleDark;
case react::RNSScreenStackHeaderConfigBlurEffect::Regular:
return UIBlurEffectStyleRegular;
case react::RNSScreenStackHeaderConfigBlurEffect::Prominent:
return UIBlurEffectStyleProminent;
case react::RNSScreenStackHeaderConfigBlurEffect::SystemUltraThinMaterial:
return UIBlurEffectStyleSystemUltraThinMaterial;
case react::RNSScreenStackHeaderConfigBlurEffect::SystemThinMaterial:
return UIBlurEffectStyleSystemThinMaterial;
case react::RNSScreenStackHeaderConfigBlurEffect::SystemMaterial:
return UIBlurEffectStyleSystemMaterial;
case react::RNSScreenStackHeaderConfigBlurEffect::SystemThickMaterial:
return UIBlurEffectStyleSystemThickMaterial;
case react::RNSScreenStackHeaderConfigBlurEffect::SystemChromeMaterial:
return UIBlurEffectStyleSystemChromeMaterial;
case react::RNSScreenStackHeaderConfigBlurEffect::SystemUltraThinMaterialLight:
return UIBlurEffectStyleSystemUltraThinMaterialLight;
case react::RNSScreenStackHeaderConfigBlurEffect::SystemThinMaterialLight:
return UIBlurEffectStyleSystemThinMaterialLight;
case react::RNSScreenStackHeaderConfigBlurEffect::SystemMaterialLight:
return UIBlurEffectStyleSystemMaterialLight;
case react::RNSScreenStackHeaderConfigBlurEffect::SystemThickMaterialLight:
return UIBlurEffectStyleSystemThickMaterialLight;
case react::RNSScreenStackHeaderConfigBlurEffect::SystemChromeMaterialLight:
return UIBlurEffectStyleSystemChromeMaterialLight;
case react::RNSScreenStackHeaderConfigBlurEffect::SystemUltraThinMaterialDark:
return UIBlurEffectStyleSystemUltraThinMaterialDark;
case react::RNSScreenStackHeaderConfigBlurEffect::SystemThinMaterialDark:
return UIBlurEffectStyleSystemThinMaterialDark;
case react::RNSScreenStackHeaderConfigBlurEffect::SystemMaterialDark:
return UIBlurEffectStyleSystemMaterialDark;
case react::RNSScreenStackHeaderConfigBlurEffect::SystemThickMaterialDark:
return UIBlurEffectStyleSystemThickMaterialDark;
case react::RNSScreenStackHeaderConfigBlurEffect::SystemChromeMaterialDark:
return UIBlurEffectStyleSystemChromeMaterialDark;
}
}
#endif

switch (blurEffect) {
case react::RNSScreenStackHeaderConfigBlurEffect::Light:
return UIBlurEffectStyleLight;
case react::RNSScreenStackHeaderConfigBlurEffect::Dark:
return UIBlurEffectStyleDark;
case react::RNSScreenStackHeaderConfigBlurEffect::Regular:
return UIBlurEffectStyleRegular;
case react::RNSScreenStackHeaderConfigBlurEffect::Prominent:
return UIBlurEffectStyleProminent;
case react::RNSScreenStackHeaderConfigBlurEffect::ExtraLight:
default:
return UIBlurEffectStyleExtraLight;
}
}

@end

#endif // RCT_NEW_ARCH_ENABLED
2 changes: 1 addition & 1 deletion ios/RNSScreenStackHeaderConfig.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@
#ifdef RCT_NEW_ARCH_ENABLED
@property (nonatomic) BOOL show;
#else
@property (nonatomic) UIBlurEffectStyle blurEffect;
@property (nonatomic) BOOL hide;
#endif

Expand Down Expand Up @@ -56,6 +55,7 @@
@property (nonatomic) BOOL backButtonInCustomView;
@property (nonatomic) UISemanticContentAttribute direction;
@property (nonatomic) UINavigationItemBackButtonDisplayMode backButtonDisplayMode;
@property (nonatomic) UIBlurEffectStyle blurEffect;

+ (void)willShowViewController:(UIViewController *)vc
animated:(BOOL)animated
Expand Down
8 changes: 4 additions & 4 deletions ios/RNSScreenStackHeaderConfig.mm
Original file line number Diff line number Diff line change
Expand Up @@ -383,13 +383,9 @@ + (UINavigationBarAppearance *)buildAppearance:(UIViewController *)vc
appearance.backgroundColor = config.backgroundColor;
}

// TODO: implement blurEffect on Fabric
#ifdef RCT_NEW_ARCH_ENABLED
#else
if (config.blurEffect) {
appearance.backgroundEffect = [UIBlurEffect effectWithStyle:config.blurEffect];
}
#endif

if (config.hideShadow) {
appearance.shadowColor = nil;
Expand Down Expand Up @@ -904,6 +900,10 @@ - (void)updateProps:(react::Props::Shared const &)props oldProps:(react::Props::
_color = RCTUIColorFromSharedColor(newScreenProps.color);
_backgroundColor = RCTUIColorFromSharedColor(newScreenProps.backgroundColor);

if (newScreenProps.blurEffect != oldScreenProps.blurEffect) {
_blurEffect = [RNSConvert UIBlurEffectStyleFromCppEquivalent:newScreenProps.blurEffect];
}

[self updateViewControllerIfNeeded];

if (needsNavigationControllerLayout) {
Expand Down
23 changes: 23 additions & 0 deletions src/fabric/ScreenStackHeaderConfigNativeComponent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,28 @@ type OnDetachedEvent = Readonly<{}>;

type BackButtonDisplayMode = 'minimal' | 'default' | 'generic';

type BlurEffect =
| 'extraLight'
| 'light'
| 'dark'
| 'regular'
| 'prominent'
| 'systemUltraThinMaterial'
| 'systemThinMaterial'
| 'systemMaterial'
| 'systemThickMaterial'
| 'systemChromeMaterial'
| 'systemUltraThinMaterialLight'
| 'systemThinMaterialLight'
| 'systemMaterialLight'
| 'systemThickMaterialLight'
| 'systemChromeMaterialLight'
| 'systemUltraThinMaterialDark'
| 'systemThinMaterialDark'
| 'systemMaterialDark'
| 'systemThickMaterialDark'
| 'systemChromeMaterialDark';

export interface NativeProps extends ViewProps {
onAttached?: DirectEventHandler<OnAttachedEvent>;
onDetached?: DirectEventHandler<OnDetachedEvent>;
Expand Down Expand Up @@ -44,6 +66,7 @@ export interface NativeProps extends ViewProps {
backButtonDisplayMode?: WithDefault<BackButtonDisplayMode, 'default'>;
hideBackButton?: boolean;
backButtonInCustomView?: boolean;
blurEffect?: WithDefault<BlurEffect, 'extraLight'>;
// TODO: implement this props on iOS
topInsetEnabled?: boolean;
}
Expand Down
Loading