「这是我参与2022首次更文挑战的第17天,活动详情查看:2022首次更文挑战」。

前言

需求:同一个模块的主题要求是一致的 实现:通过自定义导航条来进行统一控制样式

  • 设置导航条渐变颜色
  • 设置全局导航条按钮主题
  • 拦截push: 通过自定义类,重写自带的方法实现

I 自定义导航栏

iOS小技能:自定义导航栏,设置全局导航条外观。(iOS15适配)

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逆向,只为你呈现有价值的信息,专注于移动端技术研究领域。