美文网首页
iOS 封装UINavigationController

iOS 封装UINavigationController

作者: 秋燕归 | 来源:发表于2024-06-27 09:14 被阅读0次

0.相关类见《iOS 封装UIViewController》

1.配置类

//
//  SFNavigationControllerConfig.h
//  template
//
//  Created by shefeng on 2024/6/24.
//

#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>

NS_ASSUME_NONNULL_BEGIN

@interface SFNavigationControllerConfig : NSObject

/**
 *  背景色
 */
@property (strong, nonatomic) UIColor *bgColor;

/**
 *  阴影色
 */
@property (strong, nonatomic) UIColor *shadowColor;

/**
 *  返回按钮图片名称
 */
@property (strong, nonatomic) NSString *backImageName;

/**
 *  标题颜色
 */
@property (strong, nonatomic) UIColor *titleColor;

/**
 *  标题字体
 */
@property (strong, nonatomic) UIFont *titleFont;


/**
 *  单例
 */
+ (instancetype)sharedConfig;

@end

NS_ASSUME_NONNULL_END

//
//  SFNavigationControllerConfig.m
//  template
//
//  Created by shefeng on 2024/6/24.
//

#import "SFNavigationControllerConfig.h"

@implementation SFNavigationControllerConfig

+ (instancetype)sharedConfig{
    static dispatch_once_t onceToken;
    static SFNavigationControllerConfig *instance;
    dispatch_once(&onceToken, ^{
        instance = [[SFNavigationControllerConfig alloc] init];
    });
    return instance;
}

- (UIColor *)bgColor{
    if (_bgColor == nil) {
        _bgColor = [UIColor whiteColor];
    }
    return _bgColor;
}

- (UIColor *)shadowColor{
    if (_shadowColor == nil) {
        _shadowColor = [UIColor clearColor];
    }
    return _shadowColor;
}

- (NSString *)backImageName{
    if (_backImageName == nil) {
        _backImageName = @"";
    }
    return _backImageName;
}

- (UIColor *)titleColor{
    if (_titleColor == nil) {
        _titleColor = [UIColor blackColor];
    }
    return _titleColor;
}

- (UIFont *)titleFont{
    if (_titleFont == nil) {
        _titleFont = [UIFont systemFontOfSize:16];
    }
    return _titleFont;
}

@end

3.基类

//
//  SFBaseNavigationController.h
//  template
//
//  Created by shefeng on 2024/6/24.
//

#import <UIKit/UIKit.h>

NS_ASSUME_NONNULL_BEGIN

@interface SFBaseNavigationController : UINavigationController

/**
 *  根据图片、按钮样式、事件设置导航栏按钮
 *
 *  @param navItem 导航栏item
 *  @param image 图片
 *  @param style 按钮样式
 *  @param isLeft 是否是左边
 */
- (void)configBarButtonItem:(UINavigationItem *)navItem image:(UIImage *)image style:(UIBarButtonItemStyle)style target:(id)target action:(SEL)action isLeft:(BOOL)isLeft;

/**
 *  根据标题、标题属性、按钮样式、事件设置导航栏按钮
 *
 *  @param navItem 导航栏item
 *  @param text 标题
 *  @param textAttr 标题属性
 *  @param style 按钮样式
 *  @param isLeft 是否是左边
 */
- (void)configBarButtonItem:(UINavigationItem *)navItem text:(NSString *)text textAttr:(NSDictionary *)textAttr style:(UIBarButtonItemStyle)style target:(id)target action:(SEL)action isLeft:(BOOL)isLeft;

/**
 *  根据UIBarButtonItem设置导航栏按钮
 *
 *  @param navItem 导航栏item
 *  @param barButtonItem 按钮
 *  @param isLeft 是否是左边
 */
- (void)configBarButtonItem:(UINavigationItem *)navItem barButtonItem:(UIBarButtonItem *)barButtonItem isLeft:(BOOL)isLeft;

/**
 *  根据UIBarButtonItems设置导航栏按钮
 *
 *  @param navItem 导航栏item
 *  @param barButtonItems 按钮集合
 *  @param isLeft 是否是左边
 */
- (void)configBarButtonItem:(UINavigationItem *)navItem barButtonItems:(NSArray<UIBarButtonItem *> *)barButtonItems isLeft:(BOOL)isLeft;

/**
 *  根据自定义视图设置导航栏按钮
 *
 *  @param navItem 导航栏item
 *  @param customView 自定义视图
 *  @param isLeft 是否是左边
 */
- (void)configBarButtonItem:(UINavigationItem *)navItem customView:(UIView *)customView isLeft:(BOOL)isLeft;

/**
 *  配置导航栏属性
 *
 *  @param navigationBar 导航栏
 */
- (void)configCustomNavigationBarProp:(UINavigationBar *)navigationBar;

/**
 *  获取屏幕边框区域pan手势
 */
- (UIScreenEdgePanGestureRecognizer *)screenEdgePanGestureRecognizer;

@end

NS_ASSUME_NONNULL_END

//
//  SFBaseNavigationController.m
//  template
//
//  Created by shefeng on 2024/6/24.
//

#import "SFBaseNavigationController.h"
#import "SFBaseViewController.h"
#import "SFNavigationControllerConfig.h"
#import "UIImage+SFUtil.h"

@interface SFBaseNavigationController ()<UIGestureRecognizerDelegate,UINavigationControllerDelegate>

@end

@implementation SFBaseNavigationController

- (void)viewDidLoad {
    [super viewDidLoad];
    
}

/**
 *  重写initWithRootViewController方法设置代理
 *  @param rootViewController 根视图
 *  @return 实例
 */
- (id)initWithRootViewController:(UIViewController *)rootViewController {
    SFBaseNavigationController *nav = [super initWithRootViewController:rootViewController];
    nav.interactivePopGestureRecognizer.delegate = self;
    nav.delegate = self;
    return nav;
}

#pragma mark - UINavigationItem相关
/**
 *  根据图片、按钮样式、事件设置导航栏按钮
 *
 *  @param navItem 导航栏item
 *  @param image 图片
 *  @param style 按钮样式
 *  @param isLeft 是否是左边
 */
- (void)configBarButtonItem:(UINavigationItem *)navItem image:(UIImage *)image style:(UIBarButtonItemStyle)style target:(id)target action:(SEL)action isLeft:(BOOL)isLeft{
    //[image imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal] => 保持原色
    UIImage *originalImage = [image imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
    [self configBarButtonItem:navItem barButtonItem:[[UIBarButtonItem alloc] initWithImage:originalImage style:style target:target action:action] isLeft:isLeft];
}

/**
 *  根据标题、标题属性、按钮样式、事件设置导航栏按钮
 *
 *  @param navItem 导航栏item
 *  @param text 标题
 *  @param textAttr 标题属性
 *  @param style 按钮样式
 *  @param isLeft 是否是左边
 */
- (void)configBarButtonItem:(UINavigationItem *)navItem text:(NSString *)text textAttr:(NSDictionary *)textAttr style:(UIBarButtonItemStyle)style target:(id)target action:(SEL)action isLeft:(BOOL)isLeft{
    UIBarButtonItem *barButtonItem = [[UIBarButtonItem alloc] initWithTitle:text style:style target:target action:action];
    
    if (textAttr && textAttr.allKeys.count > 0) {
        [barButtonItem setTitleTextAttributes:textAttr forState:UIControlStateNormal];
    }
    
    [self configBarButtonItem:navItem barButtonItem:barButtonItem isLeft:isLeft];
}

/**
 *  根据UIBarButtonItem设置导航栏按钮
 *
 *  @param navItem 导航栏item
 *  @param barButtonItems 按钮集合
 *  @param isLeft 是否是左边
 */
- (void)configBarButtonItem:(UINavigationItem *)navItem barButtonItems:(NSArray<UIBarButtonItem *> *)barButtonItems isLeft:(BOOL)isLeft{
    if (isLeft) {
        navItem.leftBarButtonItems = barButtonItems;
    }else{
        navItem.rightBarButtonItems = barButtonItems;
    }
}

/**
 *  根据自定义视图设置导航栏按钮
 *
 *  @param navItem 导航栏item
 *  @param customView 自定义视图
 *  @param isLeft 是否是左边
 */
- (void)configBarButtonItem:(UINavigationItem *)navItem customView:(UIView *)customView isLeft:(BOOL)isLeft{
    [self configBarButtonItem:navItem barButtonItem:[[UIBarButtonItem alloc] initWithCustomView:customView] isLeft:isLeft];
}

/**
 *  根据UIBarButtonItem设置导航栏按钮
 *
 *  @param navItem 导航栏item
 *  @param barButtonItem 按钮
 *  @param isLeft 是否是左边
 */
- (void)configBarButtonItem:(UINavigationItem *)navItem barButtonItem:(UIBarButtonItem *)barButtonItem isLeft:(BOOL)isLeft{
    if (isLeft) {
        navItem.leftBarButtonItem = barButtonItem;
    }else{
        navItem.rightBarButtonItem = barButtonItem;
    }
}

/**
 *  配置导航栏属性
 *  
 *  @param navigationBar 导航栏
 */
- (void)configCustomNavigationBarProp:(UINavigationBar *)navigationBar{
    UIImage *bgImage = [UIImage createImageWithColor:[SFNavigationControllerConfig sharedConfig].bgColor size:CGSizeMake(1, 1)];
    UIImage *shadowImage = [UIImage createImageWithColor:[SFNavigationControllerConfig sharedConfig].shadowColor size:CGSizeMake(1, 1)];
    NSDictionary *titleTextAttr = @{
        NSForegroundColorAttributeName:[SFNavigationControllerConfig sharedConfig].titleColor,
        NSFontAttributeName:[SFNavigationControllerConfig sharedConfig].titleFont
    };
    
    if (@available(iOS 15.0, *)) {
        UINavigationBarAppearance *appearance = [UINavigationBarAppearance new];
        [appearance configureWithDefaultBackground];
        [appearance setBackgroundColor:[SFNavigationControllerConfig sharedConfig].bgColor];
        [appearance setBackgroundImage:bgImage];
        [appearance setShadowImage:shadowImage];
        [appearance setTitleTextAttributes:titleTextAttr];
        
        navigationBar.standardAppearance = appearance;
        navigationBar.scrollEdgeAppearance = appearance;
    }else{
        navigationBar.translucent = NO;
        [navigationBar setBackgroundColor:[SFNavigationControllerConfig sharedConfig].bgColor];
        [navigationBar setBackgroundImage:bgImage forBarMetrics:UIBarMetricsDefault];
        [navigationBar setShadowImage:shadowImage];
        [navigationBar setTitleTextAttributes:titleTextAttr];
    }
}

#pragma mark - UINavigationControllerDelegate
- (void)navigationController:(UINavigationController *)navigationController didShowViewController:(UIViewController *)viewController animated:(BOOL)animated {
   
}


#pragma mark - UIGestureRecognizerDelegate
- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer {
    if (gestureRecognizer == self.interactivePopGestureRecognizer) {
        if (self.viewControllers.lastObject == self.topViewController && self.viewControllers.count > 1) {
            if([self.topViewController isKindOfClass:[SFBaseViewController class]]) {
                SFBaseViewController *baseViewController = (SFBaseViewController *)self.topViewController;
                return baseViewController.enableSideslip;
            }
            return YES;
        }
        return NO;
    }

    return YES;
}

- (UIScreenEdgePanGestureRecognizer *)screenEdgePanGestureRecognizer {
    UIScreenEdgePanGestureRecognizer *screenEdgePanGestureRecognizer = nil;
    if (self.view.gestureRecognizers.count > 0) {
        for (UIGestureRecognizer *recognizer in self.view.gestureRecognizers) {
            if ([recognizer isKindOfClass:[UIScreenEdgePanGestureRecognizer class]]) {
                screenEdgePanGestureRecognizer = (UIScreenEdgePanGestureRecognizer *)recognizer;
                break;
            }
        }
    }
    return screenEdgePanGestureRecognizer;
}

@end

4.配置

    [SFNavigationControllerConfig sharedConfig].backImageName = @"icon_nav_back";
    [SFNavigationControllerConfig sharedConfig].bgColor = [UIColor whiteColor];
    [SFNavigationControllerConfig sharedConfig].shadowColor = [UIColor clearColor];
    [SFNavigationControllerConfig sharedConfig].titleFont = [UIFont boldSystemFontOfSize:18];
    [SFNavigationControllerConfig sharedConfig].titleColor = [UIColor blackColor];

5.使用

继承即可使用

相关文章

网友评论

      本文标题:iOS 封装UINavigationController

      本文链接:https://www.haomeiwen.com/subject/lxdjcjtx.html