l1Dan's blog

日常记录,坐标深圳

0%

NXNavigationExtension 使用

🔥 NXNavigationExtension 是为 iOS 应用设计的一个简单、易用的导航栏处理框架。框架对现有代码入侵非常小,只需要简单的几个方法调用就可以满足大部分的应用场景。NXNavigationExtension 和 示例程序代码 都已经适配暗黑模式(Dark Mode)。

🎉 预览

🌟 开始使用

下载 NXNavigationExtension 示例程序代码。

使用 CocoaPods 安装

使用 CocoaPods 将 NXNavigationExtension 集成到 Xcode 项目中,需要在 Podfile 中指定:

1
pod 'NXNavigationExtension'

或者

1
pod 'NXNavigationExtension', ~> 3.0.0

使用 Carthage 安装

Carthage 是一个去中心化的包管理器,它构建依赖项并为您提供二进制框架。 要集成 NXNavigationExtension,请将以下内容添加到您的 Cartfile 文件中:

1
github "l1Dan/NXNavigationExtension"

或者

1
github "l1Dan/NXNavigationExtension" ~> 3.0.0

使用 Swift Package Manager 安装

添加 NXNavigationExtension 依赖库到 Package.swiftdependencies 中。

1
2
3
dependencies: [
.package(url: "https://github.com/l1Dan/NXNavigationExtension.git", .upToNextMajor(from: "3.0.0"))
]

🌈 要求

NXNavigationExtension Version Minimum iOS Target Minimum macOS Target Minimum watchOS Target Minimum tvOS Target Notes
3.x iOS 11 macOS 10.15 n/a n/a macOS: macCatalyst
2.x iOS 11 macOS 10.15 n/a n/a macOS: macCatalyst

优点

  • API 设计通俗易懂,容易上手。
  • 没有继承关系,所有操作基于方法重写,对项目入侵较小。
  • 按需注册需要控制的 UINavigationController 子类,不会影响全局外观。
  • 没有对原生导航栏视图层级进行修改,无需担心升级系统兼容性问题。
  • 适配 iOS、iPadOS、macOS,Dark Mode。
  • 支持 CocoaPods、Carthage、SPM(Swift5.x)、Project 方式集成。

👏 功能

特别实用的功能,总有一款适合你的项目

基本功能

  • 设置导航栏透明
  • 设置导航栏半透明
  • 自定义返回按钮图片
  • 自定义返回按钮
  • 自定义导航栏模糊背景
  • 修改返回按钮箭头颜色
  • 修改导航栏标题颜色
  • 修改导航栏背景颜色
  • 修改导航栏背景图片
  • 修改导航栏底部线条颜色
  • 修改导航栏底部线条颜色图片

高级功能

  • 禁用滑动返回手势
  • 启用全屏滑动返回手势
  • 导航栏返回事件拦截
  • 重定向任一控制器跳转
  • 导航栏点击事件穿透到底部
  • 动态修改导航栏样式
  • 更新导航栏样式

🍽 使用

所有对导航栏外观的修改都是基于视图控制器 UIViewController 修改的,而不是基于导航控制器 UINavigationController 修改,这种设计逻辑更加符合实际应用场景。也就是自己所在的导航栏的外观自己管理。

  1. 💉 导入头文件 #import <NXNavigationExtension/NXNavigationExtension.h>
  2. 💉 使用之前需要先注册需要修改的导航控制器,以 FeatureNavigationController 为例:
1
[NXNavigationBar registerStandardAppearanceForNavigationControllerClass:[FeatureNavigationController class]];

注意

  • 👉 使用之前需要先注册导航控制器,注册之后对导航栏的修改才会生效,也仅限于修改注册的导航控制器所管理的视图控制器,对于子类导航控制器所管理的视图控制器是不会生效的,这样可以有效避免框架污染到其他的导航控制器,保持“谁使用,谁注册”的原则。
  • 🚫 不要直接注册 UINavigationController,这个影响全局导航栏的外观,建议创建一个 UINavigationController 的子类,对这个类进行注册。
  • 🚫 不要使用系统导航栏隐藏、显示方法, setNavigationBarHidden:setNavigationBarHidden:animatedsetHidden:
  • 🚫 不要使用系统导航栏修改透明度。
  • 🚫 不要使用系统导航栏或导航控制器 appearance 相关属性修改。
  • 🚫 不要使用全局 edgesForExtendedLayout 修改。
  • 🚫 不要使用 <UIGestureRecognizerDelegate> 相关方法禁用手势返回。
  • 💉 一句话“不要直接操作导航栏或者导航控制器,把这些都交给 NXNavigationExtension 处理吧“。

建议:除非你非常明白修改全局性东西的后果,否则不要修改,这么做的原因就是为了减少走一些弯路!

🍻 基本功能

修改返回按钮箭头颜色

📝 示例代码

导航栏返回按钮颜色默认使用系统蓝色 [UIColor systemBlueColor],要改变返回按钮颜色可以使用以下方式配合:

1
2
3
4
5
6
7
// 全局统一修改,不会覆盖基于视图控制器修改
NXNavigationBarAppearance.standardAppearance.tintColor = [UIColor redColor];

// 基于视图控制器修改
- (UIColor *)nx_barTintColor {
return self.isDarkMode ? [UIColor whiteColor] : [UIColor blackColor];
}

修改导航栏标题颜色

📝 示例代码

1
2
3
- (NSDictionary<NSAttributedStringKey,id> *)nx_titleTextAttributes {
return @{NSForegroundColorAttributeName: [self nx_barTintColor]};
}

修改导航栏背景颜色

📝 示例代码

1
2
3
- (UIColor *)nx_navigationBarBackgroundColor {
return [UIColor customDarkGrayColor];
}

修改导航栏背景图片

📝 示例代码

1
2
3
- (UIImage *)nx_navigationBarBackgroundImage {
return UIImage.navigationBarBackgorundImage;
}

设置导航栏透明

📝 示例代码

1
2
3
- (UIColor *)nx_navigationBarBackgroundColor {
return [UIColor clearColor];
}

设置导航栏半透明

📝 示例代码

1
2
3
- (BOOL)nx_useSystemBlurNavigationBar {
return YES;
}

修改导航栏底部线条颜色

📝 示例代码

1
2
3
- (UIColor *)nx_shadowImageTintColor {
return [UIColor redColor];
}

修改导航栏底部线条颜色图片

📝 示例代码

1
2
3
- (UIColor *)nx_shadowImageTintColor {
return [UIColor redColor];
}

修改导航栏底部线条颜色图片

📝 示例代码

1
2
3
- (UIImage *)nx_shadowImage {
return [UIImage imageNamed:@"NavigationBarShadowImage"];
}

自定义返回按钮图片

📝 示例代码

1
2
3
- (UIImage *)nx_backImage {
return [UIImage imageNamed:@"NavigationBarBack"];
}

自定义返回按钮

📝 示例代码

1
2
3
4
5
6
7
- (UIView *)nx_backButtonCustomView {
UIButton *backButton = [UIButton buttonWithType:UIButtonTypeCustom];
[backButton setTitle:@"😋" forState:UIControlStateNormal];
[backButton setImage:[UIImage imageNamed:@"NavigationBarBack"] forState:UIControlStateNormal];
[backButton setTitleColor:UIColor.customDarkGrayColor forState:UIControlStateNormal];
return backButton;
}

🍺 高级功能

禁用滑动返回手势

📝 示例代码

1
2
3
- (BOOL)nx_disableInteractivePopGesture {
return YES;
}

启用全屏滑动返回手势

📝 示例代码

  • 局部有效(在所处页面设置)
1
2
3
- (BOOL)nx_enableFullScreenInteractivePopGesture {
return YES;
}
  • 全局有效(在注册导航栏之前设置)
1
NXNavigationExtensionFullscreenPopGestureEnable = YES;

导航栏返回事件拦截

📝 示例代码

需要遵守协议 <UINavigationControllerCustomizable>,实现代理方法:

1
2
3
4
- (BOOL)navigationController:(__kindof UINavigationController *)navigationController willPopViewControllerUsingInteractingGesture:(BOOL)interactingGesture {
// TODO...
return YES;
}
  • 拦截点击返回按钮事件 & 手势返回事件
  • 拦截点击返回按钮事件
  • 拦截手势返回事件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
- (BOOL)navigationController:(__kindof UINavigationController *)navigationController willPopViewControllerUsingInteractingGesture:(BOOL)interactingGesture {
if (self.currentItemType == EventInterceptItemTypeBoth) { // 拦截点击返回按钮事件 & 手势返回事件
[self showAlertController];
return NO;
}

if (self.currentItemType == EventInterceptItemTypeBackButton) { // 拦截点击返回按钮事件
if (!interactingGesture) {
[self showAlertController];
return NO;
}
}

if (self.currentItemType == EventInterceptItemTypePopGesture) { // 拦截手势返回事件
if (interactingGesture) {
[self showAlertController];
return NO;
}
}

return YES;
}

自定义返回按钮事件拦截需要调用方法:[self.navigationController nx_triggerSystemBackButtonHandler];

重定向任一控制器跳转

📝 示例代码

  • 以重定向到 RandomColorViewController 为例,如果之前有 Push 过 RandomColorViewController 的实例,则最后会跳转到实例中,如果没有则会调用 block,如果 block == NULL 或者 return nil; 则重定向跳转不会发生。
  • 执行重定向操作之后,并不会直接跳转到对应的视图控制器,如果需要 跳转 操作,可以调用 popViewControllerAnimated:使用手势返回点击返回按钮返回
1
2
3
[self.navigationController nx_redirectViewControllerClass:[RandomColorViewController class] createViewControllerUsingBlock:^__kindof UIViewController * _Nonnull {
return [[RandomColorViewController alloc] init];
}];

注意
执行上面代码之后并不会立即跳转,下面代码可以实现立即跳转:

1
2
3
4
[self.navigationController nx_redirectViewControllerClass:[RandomColorViewController class] createViewControllerUsingBlock:^__kindof UIViewController * _Nonnull {
return [[RandomColorViewController alloc] init];
}];
[self.navigationController popViewControllerAnimated:YES];

上面代码大意为:首先查找 self.navigationController.ViewConrollers 是否存在一个类型为 [RandomColorViewController class] 的实例对象,如果存在则重定向到此视图控制器,没有则使用 [[RandomColorViewController alloc] init] 来创建一个新的 [RandomColorViewController class] 的实例对象。

导航栏点击事件穿透到底部

📝 示例代码

1
2
3
- (BOOL)nx_hidesNavigationBar {
return YES;
}

动态修改导航栏样式

📝 示例代码

1
2
3
- (BOOL)nx_containerViewWithoutNavigtionBar {
return YES;
}

可以动态调整 ContainerView 透明度实现:self.nx_navigationBar.containerView.alpha = value

更新导航栏样式

📝 示例代码

1
[self nx_setNeedsNavigationBarAppearanceUpdate];

如果状态栏样式没有发生变化,请检查是否需要调用方法 [self setNeedsStatusBarAppearanceUpdate],或者在 UINavigationController 的子类中设置如下代码:

1
2
3
4
5
6
7
- (UIViewController *)childViewControllerForStatusBarStyle {
return self.topViewController;
}

- (UIViewController *)childViewControllerForStatusBarHidden {
return self.topViewController;
}

📄 协议

NXNavigationExtension 框架是在 MIT 许可下发布的。详情请参见 LICENSE