0.相关类见《iOS 封装UINavigationController》
1.配置类
//
// SFViewControllerConfig.h
// template
//
// Created by shefeng on 2024/6/24.
//
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
@interface SFViewControllerConfig : NSObject
/**
* 背景色
*/
@property (strong, nonatomic) UIColor *bgColor;
/**
* 不受hideNavigationBar属性影响的类名集合
*/
@property (strong, nonatomic) NSMutableArray<NSString *> *ignoreClassArr;
/**
* 单例
*/
+ (instancetype)sharedConfig;
@end
NS_ASSUME_NONNULL_END
//
// SFViewControllerConfig.m
// template
//
// Created by shefeng on 2024/6/24.
//
#import "SFViewControllerConfig.h"
@implementation SFViewControllerConfig
+ (instancetype)sharedConfig{
static dispatch_once_t onceToken;
static SFViewControllerConfig *instance;
dispatch_once(&onceToken, ^{
instance = [[SFViewControllerConfig alloc] init];
});
return instance;
}
- (UIColor *)bgColor{
if (_bgColor == nil) {
_bgColor = [UIColor whiteColor];
}
return _bgColor;
}
- (NSMutableArray<NSString *> *)ignoreClassArr{
if(_ignoreClassArr == nil){
_ignoreClassArr = [NSMutableArray new];
}
return _ignoreClassArr;
}
@end
2.基类
//
// SFBaseViewController.h
// template
//
// Created by shefeng on 2024/6/24.
//
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
@interface SFBaseViewController : UIViewController
/**
* 隐藏导航栏
*/
@property (nonatomic, assign) BOOL hideNavigationBar;
/**
* 启用侧滑
*/
@property (nonatomic, assign) BOOL enableSideslip;
/**
* 解决侧滑手势和UIScrollView手势冲突的问题
*/
- (void)handleConflictOfScrollView:(UIScrollView *)scrollView;
/**
* 获取最上层VC
*/
+ (SFBaseViewController *)topViewController;
/**
* 返回事件
*/
- (void)backAction;
@end
NS_ASSUME_NONNULL_END
//
// SFBaseViewController.m
// template
//
// Created by shefeng on 2024/6/24.
//
#import "SFBaseViewController.h"
#import "SFViewControllerConfig.h"
#import "SFBaseNavigationController.h"
#import "SFNavigationControllerConfig.h"
@interface SFBaseViewController ()<UIGestureRecognizerDelegate>
@end
@implementation SFBaseViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = [SFViewControllerConfig sharedConfig].bgColor;
//判断是否有上级页面来确定是否显示返回按钮
if ([self isViewControllerPushed]) {
[self configBackBtn];
}
//设置自定义导航栏属性
[self configCustomNavBar];
}
- (void)viewWillAppear:(BOOL)animated{
[super viewWillAppear:animated];
if (![[SFViewControllerConfig sharedConfig].ignoreClassArr containsObject:NSStringFromClass([self class])]) {
[self.navigationController setNavigationBarHidden:self.hideNavigationBar animated:NO];
}
}
- (void)viewWillDisappear:(BOOL)animated{
[super viewWillDisappear:animated];
}
- (void)dealloc{
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
/**
* 解决侧滑手势和UIScrollView手势冲突的问题
*
* @param scrollView 滚动视图
*/
- (void)handleConflictOfScrollView:(UIScrollView *)scrollView{
if ([self.navigationController isKindOfClass:[SFBaseNavigationController class]]) {
SFBaseNavigationController *nav = (SFBaseNavigationController *)self.navigationController;
UIScreenEdgePanGestureRecognizer *recognizer = [nav screenEdgePanGestureRecognizer];
if (recognizer) {
[scrollView.panGestureRecognizer requireGestureRecognizerToFail:recognizer];
}
}
}
/**
* 获取最上层VC
*/
+ (SFBaseViewController*)topViewController {
return (SFBaseViewController *)[self topViewControllerWithRootViewController:[UIApplication sharedApplication].windows.firstObject.rootViewController];
}
+ (UIViewController*)topViewControllerWithRootViewController:(UIViewController*)rootViewController {
if ([rootViewController isKindOfClass:[UITabBarController class]]) {
UITabBarController *tabBarController = (UITabBarController *)rootViewController;
return [self topViewControllerWithRootViewController:tabBarController.selectedViewController];
} else if ([rootViewController isKindOfClass:[UINavigationController class]]) {
UINavigationController *navigationController = (UINavigationController *)rootViewController;
return [self topViewControllerWithRootViewController:navigationController.visibleViewController];
} else if (rootViewController.presentedViewController) {
UIViewController *presentedViewController = rootViewController.presentedViewController;
if ([presentedViewController isKindOfClass:[UIAlertController class]]) {
UIWindow *window = [UIApplication sharedApplication].delegate.window;
UIViewController *vc = window.rootViewController;
return [self topViewControllerWithRootViewController:vc];
}
return [self topViewControllerWithRootViewController:presentedViewController];
} else {
return rootViewController;
}
}
- (BOOL)isViewControllerPushed{
if (!self.navigationController) {
return NO;
}
NSArray *viewcontrollers = self.navigationController.viewControllers;
if (viewcontrollers.count >= 1) {
if (viewcontrollers.lastObject == self && viewcontrollers.firstObject != self) {
return YES;
}
}
return NO;
}
#pragma mark - 返回相关
- (void)backAction{
if([self isViewControllerPushed]){
[self.navigationController popViewControllerAnimated:YES];
}else{
[self dismissViewControllerAnimated:YES completion:nil];
}
}
- (void)configBackBtn{
UINavigationController *nav = self.navigationController;
if (nav != nil && [nav isKindOfClass:[SFBaseNavigationController class]]) {
SFBaseNavigationController *baseNav = (SFBaseNavigationController *)nav;
[baseNav configBarButtonItem:self.navigationItem image:[UIImage imageNamed:[SFNavigationControllerConfig sharedConfig].backImageName] style:UIBarButtonItemStylePlain target:self action:@selector(backAction) isLeft:YES];
}
}
- (void)configCustomNavBar{
if (self.navigationController && [self.navigationController isKindOfClass:[SFBaseNavigationController class]]) {
SFBaseNavigationController *baseNav = (SFBaseNavigationController *)self.navigationController;
[baseNav configCustomNavigationBarProp:self.navigationController.navigationBar];
}
}
@end
3.配置
[SFViewControllerConfig sharedConfig].bgColor = [UIColor grayColor];
[[SFViewControllerConfig sharedConfig].ignoreClassArr addObject:@"BViewController"];
4.使用
继承即可使用