iOS小技能:自定义导航栏,设置全局导航条外观。(iOS15适配)
「这是我参与2022首次更文挑战的第17天,活动详情查看:2022首次更文挑战」。
前言
需求:同一个模块的主题要求是一致的 实现:通过自定义导航条来进行统一控制样式
- 设置导航条渐变颜色
- 设置全局导航条按钮主题
- 拦截push: 通过自定义类,重写自带的方法实现
I 自定义导航栏
1.appstore1 自定义导航条
#import <UIKit/UIKit.h>
#import "UIBarButtonItem+Extension.h"
#import "ImageTools.h"
@interface HWNavigationController : UINavigationController
+ (void) setttingAppearance;
- (void)setupNavigationBarBarStyle:(NSInteger)barStyle;
#pragma mark - ******** 设置列表控制器的样式
+ (void)setupListnavigationItemAndBarStyle:(UIViewController*)vc;
+ (void)setupDetailnavigationItemAndBarStyle:(UIViewController*)vc;
@end
1.2 设置全局导航条按钮主题
setttingAppearance
#import "HWNavigationController.h"
#import "GYQBaseBarItem.h"
@implementation HWNavigationController
#pragma mark - 设置导航栏主题
+ (void) setttingAppearance{
//设置全局导航条外观
[self settingUINavigationBarAppearance];
if (IOS7) {
return;//不需要设置全局导航条按钮主题
}
//设置全局导航条按钮主题
[self settingbarButtonItenAppearance];
}
settingUINavigationBarAppearance
+ (void) settingUINavigationBarAppearance{
/*
@protocol UIAppearance <NSObject> 协议的代理方法+ (instancetype)appearance;
@interface UIView : UIResponder < UIAppearance>
*/
//方式一:获取全局外观
// UINavigationBar *navigationBar =[UINavigationBar appearance];//获取所有导航条外观
//方式二:获取我们自己导航控制器的导航条-- 确保系统的其它功能(短信)的导航条与自己的冲突,尤其在短信分享这方面要注意
UINavigationBar *navigationBar;
if (IOS9) {
//9.0的API
navigationBar = [UINavigationBar appearanceWhenContainedInInstancesOfClasses:@[[HWNavigationController class]]];
}else{
navigationBar = [UINavigationBar appearanceWhenContainedIn:[HWNavigationController class],nil];
}
/**
导航栏背景的出图规格
iOS6导航栏背景的出图规格
非retina:320x44 px
retina:640x88 px
iOS7导航栏背景的出图规格
retina:640x128 px
*/
[self setupUINavigationBarsetBackgroundImage:navigationBar];
/*2.
*标题:@property(nonatomic,copy) NSDictionary *titleTextAttributes;// 字典中能用到的key在UIStringDrawing.h中// 最新版本的key在UIKit框架的NSAttributedString.h中
*/
// NSDictionary *dict = @{UITextAttributeTextColor:[UIColor whiteColor]};
NSDictionary *dict = @{NSForegroundColorAttributeName:[UIColor whiteColor],NSFontAttributeName:kNavListNSFontAttributeName};
[navigationBar setTitleTextAttributes:dict];
//2、The tint color to apply to the navigation items and bar button items. 导航条的主题颜色
[navigationBar setTintColor:[UIColor whiteColor]];
}
1.3 设置导航条渐变颜色
setupUINavigationBarsetBackgroundImage
+ (void)setupUINavigationBarsetBackgroundImage:(UINavigationBar*)navigationBar{
UIImage *bgImg = [UIImage getMaingradientColorImage];
[navigationBar setBackgroundImage:bgImg forBarMetrics:UIBarMetricsDefault];
}
1.4 拦截push
#pragma mark - 拦截push;--//90%的拦截,都是通过自定义类,重写自带的方法实现
- (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated{
if (self.viewControllers.count>0) {
[self setNavigationBarHidden:NO animated:NO];
viewController.hidesBottomBarWhenPushed =YES;
if ([viewController respondsToSelector:@selector(KNbackAction)]) {
UIBarButtonItem *tmp =[[UIBarButtonItem alloc]initWithImage:[UIImage imageNamed:QCTNAVicon_left] style:0 target:viewController action:@selector(KNbackAction)];
viewController.navigationItem.leftBarButtonItem = tmp;
}else{
UIBarButtonItem *tmp =[[UIBarButtonItem alloc]initWithImage:[UIImage imageNamed:QCTNAVicon_left] style:0 target:self action:@selector(backAction)];
viewController.navigationItem.leftBarButtonItem = tmp;
}
}
[super pushViewController:viewController animated:animated];
}
#pragma mark - 重写: animated:
/**
1)自定义导航控制器的价值
重写push方法就可以拦截所有压入栈中的子控制器,统一做一些处理
*/
- (void)presentViewController:(UIViewController *)viewControllerToPresent animated:(BOOL)flag completion:(void (^)(void))completion{
// if ([[viewControllerToPresent topViewController] respondsToSelector:@selector(KNprebackAction)]) {
if ( [viewControllerToPresent isKindOfClass:[UINavigationController class]]) {
UINavigationController *viewControllerToPresenttmp = (UINavigationController*)viewControllerToPresent;
weakSelf(weakSelf);
if ([[viewControllerToPresenttmp topViewController] respondsToSelector:@selector(KNprebackAction)]) {
GYQBaseBarItem *tmp =[[GYQBaseBarItem alloc]initWithImage:[UIImage imageNamed:QCTNAVicon_left] style:0 target:[viewControllerToPresenttmp topViewController] action:@selector(KNprebackAction)];
tmp.baseVC = viewControllerToPresent;
viewControllerToPresenttmp.topViewController.navigationItem.leftBarButtonItem = tmp;
}else{
GYQBaseBarItem *tmp =[[GYQBaseBarItem alloc]initWithImage:[UIImage imageNamed:QCTNAVicon_left] style:0 target:weakSelf action:@selector(presenbackAction:)];
tmp.baseVC = viewControllerToPresent;
viewControllerToPresenttmp.topViewController.navigationItem.leftBarButtonItem = tmp;
}
}
[super presentViewController:viewControllerToPresent animated:flag completion:completion];
}
-(void)presenbackAction:(GYQBaseBarItem *)bar{
//一旦点击返回,就要打断首次流程
[bar.baseVC dismissViewControllerAnimated:YES completion:nil];
}
- (void)backAction{
[self popViewControllerAnimated:YES];
}
1.5 去掉透明后导航栏下边的黑边(iOS15适配)
iOS15之前
[self.navigationBar setShadowImage:[[UIImage alloc] init]];
iOapproachS15之后
if(@available(iOS 15.0, *)) {
UINavigationBarAppearance *appearance = [[UINavigationBarAppearance alloc] init];
//去掉透明后导航栏下边的黑边
appearance.shadowImage =[[UIImage alloc] init];
appearance.shadowColor= UIColor.clearColor;
navigationBar.standardAppearance = appearance;
navigationBar.scrollEdgeAppearance = appearance;
}
II 相关代码
宏
#define kAdjustRatio(num) (ceil((SCREENW/375.0)*(num)))
#define kPingFangFont(fontSize) [UIFont fontWithName:@"PingFang-SC-Medium" size:(kAdjustRatio(fontSize))]
#define kTextFont(size) [UIFont systemFontOfSize:(kAdjustRatio(size))]
#define kPingFangHeavyFont(fontSize) [UIFont fontWithName:@"PingFang-SC-Heavy" size:(kAdjustRatio(fontSize))]
#define kPingFangNOkAdjustRatioFont(fontSize) [UIFont fontWithName:@"PingFang-SC-Medium" size:((fontSize))]
#define kBoldFont(fontSize) [UIFont fontWithName:@"Helvetica-Bold" size:(kAdjustRatio(fontSize))]
- searchBar 的searchField 的获取
UITextField *searchField = [searchBar valueForKey:@"searchField"];
[searchField setBackgroundColor:HWColor(245, 245, 245)];
获取navigationBar
if (IOS9) {
//9.0的API
navigationBar = [UINavigationBar appearanceWhenContainedInInstancesOfClasses:@[[GYQNavigationControllerViewController class]]];
[[UIBarButtonItem appearanceWhenContainedInInstancesOfClasses:@[[UISearchBar class]]] setTintColor:[UIColor blackColor]];
}else{
navigationBar = [UINavigationBar appearanceWhenContainedIn:[GYQNavigationControllerViewController class],nil];
[[UIBarButtonItem appearanceWhenContainedIn: [UISearchBar class], nil] setTintColor:[UIColor blackColor]];
}
[navigationBar setShadowImage:[ImageTools createImageWithColor: QBW221Color]];
see alsoAPP
更多内容请关注#小程序:iOS逆向
,只为你呈现有价值的信息,专注于移动端技术研究领域。