iOS15导航栏适配
在iOS 13中,苹果给导航栏的UINavigationBar增加了scrollEdgeAppearance属性。该属性应用在iOS 14及更早版本的大标题导航栏上,在iOS 15中scrollEdgeAppearance属性开始适用于所有的导航栏
官方解释:当关联的UIScrollView到达与导航条相邻的边缘(导航条的上边缘)时需要设置导航条的外观属性。如果没有设置,将默认使用修改后的standardAppearance。
scrollEdgeAppearance 与 standardAppearance 一样同属于 UINavigationBarAppearance 类型 父类是 UIBarAppearance
其中影响导航栏颜色、阴影涉及到以下属性:
1 2 3 4 5 6 7 8
| @property (nonatomic, readwrite, copy, nullable) UINavigationBarAppearance *scrollEdgeAppearance UI_APPEARANCE_SELECTOR API_AVAILABLE(ios(13.0));
backgroundEffect 基于backgroundColor或backgroundImage的磨砂效果 backgroundColor 背景色,层级在backgroundImage之下 backgroundImage 背景图片 backgroundImageContentMode渲染backgroundImage时的内容模式。 默认是UIViewContentModeScaleToFill shadowColor 阴影颜色(底部分割线) shadowImage 阴影图片(可以使用图片的渲染模式:UIImageRenderingModeAlwaysOriginal 保持原色)
|
其中:
- 当shadowImage为nil时,直接使用此颜色为阴影色。如果此属性为nil或clearColor(需要显式设置),则不显示阴影。
- 如果shadowImage包含 template 图像,则使用该图像作为阴影并使用此属性中的值对其进行着色。如果此属性为nil或clearColor(需要显式设置),则不显示阴影。
- 如果shadowImage不包含 template 图像,则此属性无效。
兼容iOS15设置透明导航栏示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| - (void)viewWillAppear:(BOOL)animated { [super viewWillAppear:animated];]
if (@available(iOS 13.0, *)) { UINavigationBarAppearance *scrollEdgeAppearance = [UINavigationBarAppearance new]; scrollEdgeAppearance.backgroundColor = [UIColor clearColor]; scrollEdgeAppearance.backgroundEffect = nil; scrollEdgeAppearance.titleTextAttributes = @{NSForegroundColorAttributeName : [UIColor whiteColor], NSFontAttributeName : [UIFont systemFontOfSize:18]}; self.navigationController.navigationBar.scrollEdgeAppearance = nil; self.navigationController.navigationBar.standardAppearance = scrollEdgeAppearance; }else { self.navigationController.navigationBar.titleTextAttributes = @{NSForegroundColorAttributeName : [UIColor whiteColor], NSFontAttributeName : [UIFont systemFontOfSize:18]}; [self.navigationBar setShadowImage:[UIImage new]]; UIImage *barImg = [[UIImage createImageWithColor:[UIColor whiteColor] size:CGSizeMake(SCREEN_WIDTH, 44.f)] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal]; [self.navigationController.navigationBar setBackgroundImage:barImg forBarMetrics:UIBarMetricsDefault]; } self.navigationController.navigationBar.translucent = YES; self.navigationController.navigationBar.tintColor = [UIColor whiteColor]; }
|
原因分析:
因为当设置scrollEdgeAppearance = nil,当前控制器如果使用有ScrollView类的控件,当ScrollView向上滚动时scrollEdgeAppearance会默认使用standardAppearance的属性效果。所以backgroundEffect和shadowColor属性需要显式设置为nil,以防止backgroundEffect、shadowColor有颜色值影响导航栏透明效果。
兼容iOS15设置不透明纯色导航栏示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| - (void)viewWillAppear:(BOOL)animated { ……
if (@available(iOS 13.0, *)) { UINavigationBarAppearance *scrollEdgeAppearance = [UINavigationBarAppearance new]; scrollEdgeAppearance.backgroundColor = [UIColor whiteColor]; //基于backgroundColor或backgroundImage的磨砂效果 scrollEdgeAppearance.backgroundEffect = nil; //阴影颜色(底部分割线),当shadowImage为nil时,直接使用此颜色为阴影色。如果此属性为nil或clearColor(需要显式设置),则不显示阴影。 scrollEdgeAppearance.shadowColor = nil; …… }else { // For Earlier version …… } //透明设置 包括原有的导航栏设置 需要保持 self.navigationController.navigationBar.translucent = NO; //navigationItem控件的颜色 self.navigationController.navigationBar.tintColor = [UIColor blackColor]; }
|
参考:
- https://developer.apple.com/documentation/uikit/uinavigationbar/3198027-scrolledgeappearance?language=objc
- https://www.jianshu.com/p/23c1c4db3f2c