🔥 NXNavigationExtension 是为 UINavigationBar 设计的轻量级的、简单的、可扩展的库,支持 SwiftUI 和 UIKit。框架对现有代码入侵非常小,只需要简单的几个方法调用就可以满足大部分的应用场景。可能是最省心的 iOS 导航栏处理框架之一。NXNavigationExtension 框架本身和示例代码都已经适配暗黑模式可供大家参考。
SwiftUI 路由 | 完全自定义导航栏 | 返回事件拦截 | 修改导航栏外观 |
---|---|---|---|
Version | Minimum iOS / macOS Target | Frameworks | Note |
---|---|---|---|
4.1.7 Later | iOS 12.0 / macOS 10.15 | SwiftUI、UIKit、macCatalyst | Xcode15 |
4.1.5 Later | iOS 11.0 / macOS 10.15 | SwiftUI、UIKit、macCatalyst | Xcode14 |
4.1.4 | iOS 9.0 / macOS 10.15 | SwiftUI、UIKit、macCatalyst | Xcode13 |
3.x | iOS 9.0 / macOS 10.15 | UIKit、macCatalyst | / |
2.x | iOS 11.0 / macOS 10.15 | UIKit、macCatalyst | / |
下面这些特别实用的功能,总有一部分适合你的项目
设置导航栏透明
实现系统导航栏模糊效果
自定义返回按钮图片
自定义返回按钮
自定义导航栏模糊背景
修改返回按钮箭头颜色
修改系统返回按钮文字
修改导航栏标题颜色
修改导航栏背景颜色
修改导航栏背景图片
设置导航栏底部阴影颜色
设置导航栏底部阴影图片
禁用右滑手势返回
启用全屏右滑手势返回
导航栏返回事件拦截
支持视图控制器转场状态
SwiftUI 路由
导航栏点击事件穿透到底部
动态修改导航栏样式
更新导航栏样式
渐变导航栏样式
长按返回按钮显示菜单功能
下载 NXNavigationExtension 示例代码。
使用 CocoaPods 将 NXNavigationExtension 集成到 Xcode 项目中,需要在 Podfile
中指定:
## For SwiftUI
pod 'NXNavigationExtension/SwiftUI'
## For UIKit
pod 'NXNavigationExtension'
使用 Carthage 管理 NXNavigationExtension framework,请将以下内容添加到您的 Cartfile
文件中:
# For SwiftUI
github "l1Dan/NXNavigationExtension" # Requires
github "l1Dan/NXNavigationExtensionSwiftUI"
# For UIKit
github "l1Dan/NXNavigationExtension"
使用 Swift Package Manager 集成 NXNavigationExtension,请将以下内容添加到您的 Package.swift
文件的依赖中:
dependencies: [
.package(url: "https://github.com/l1Dan/NXNavigationExtension.git", .upToNextMajor(from: "4.2.3"))
]
所有对导航栏外观的修改都是基于视图控制器 UIViewController
修改的,而不是基于导航控制器 UINavigationController
修改,这种设计逻辑更加符合实际应用场景。也就是说视图控制器管理自己的导航栏,而不是使用导航控制器来全局管理。
import NXNavigationExtension
。AppDelegate
中注册需要修改的导航控制器。✅ 推荐
只需要下面这一行代码就完成导航控制器的注册,现在你可以尽情地修改导航栏的外观了。
// For YourNavigationController
NXNavigationConfiguration().registerNavigationControllerClasses([YourNavigationController.self])
或者
当然也可以同时注册多个导航控制器
NXNavigationConfiguration().registerNavigationControllerClasses([YourNavigationController.self, YourNavigationController2.self])
或者
还可以动态修改导航栏的外观(NXNavigationExtensionSwiftUI
框架就是基于这个特性实现的)
let configuration = NXNavigationConfiguration.default
// 默认首选配置(单利对象意味着对所有注册的导航控制器生效)
configuration.navigationBarAppearance.tintColor = .customTitle
configuration.registerNavigationControllerClasses([YourNavigationController.self, YourNavigationController2.self]) { navigationController, configuration in
// For UINavigationController,针对不同导航控制器的修改
if navigationController is YourNavigationController {
// 动态修改导航控制器的默认首选配置
configuration.navigationBarAppearance.backgroundColor = .brown
// 动态修改视图控制器的默认首选配置
navigationController.nx_prepareConfigureViewControllersCallback { viewController, configuration in
// For UIViewController 针对不同视图控制器的修改
if viewController is MyViewController {
configuration.navigationBarAppearance.backgroundColor = .red
}
}
}
return configuration
}
❌ 不推荐
// UINavigationController 会影响所有的导航控制器,所以不推荐使用这种方式注册
NXNavigationConfiguration().registerNavigationControllerClasses([UINavigationController.self])
注意:
Swift
语言实现的,但框架还是可以支持 Objective-C
语言的,如果需要 Objective-C
示例程序的代码可以查看 3.x 分支代码。UINavigationController
,会影响全局导航栏的外观,建议创建一个 UINavigationController
的子类,对这个子类进行外观的设置。setNavigationBarHidden:
、setNavigationBarHidden:animated
、setHidden:
等方法显示或隐藏系统导航栏。appearance
相关属性修改。<UIGestureRecognizerDelegate>
相关方法禁用手势返回。edgesForExtendedLayout = UIRectEdge(rawValue: 0)
属性设置,使用默认方式即可,具体原因请查看。📝 示例代码
override var nx_barTintColor: UIColor? {
return isDarkMode ? .white : .black
}
📝 示例代码
// 需要设置使用系统返回按钮,这样才会有效果
override var nx_useSystemBackButton: Bool {
return true
}
override var nx_systemBackButtonTitle: String? {
return backButtonTitle
}
📝 示例代码
override var nx_titleTextAttributes: [NSAttributedString.Key : Any]? {
return [NSAttributedString.Key.foregroundColor: nx_barTintColor ?? (isDarkMode ? .white : .black)]
}
导航栏背景颜色默认使用系统蓝色 UIColor.systemBlue
,这样处理能够快速辨别框架是否生效,也可以使用以下方式进行重写:
📝 示例代码
// 全局统一修改(不会覆盖基于视图控制器的修改)
let configuration = NXNavigationConfiguration.default
configuration.navigationBarAppearance.backgroundColor = .red
// 基于视图控制器修改(可以是基类视图控制器也是可以是特定需要修改的视图控制器)
override var nx_navigationBarBackgroundColor: UIColor? {
return randomColor
}
📝 示例代码
override var nx_navigationBarBackgroundImage: UIImage? {
return UIImage.navigationBarBackground
}
📝 示例代码
override var nx_navigationBarBackgroundColor: UIColor? {
return .clear
}
// 设置导航栏底部阴影颜色
override var nx_shadowColor: UIColor? {
return .clear
}
📝 示例代码
override var nx_navigationBarBackgroundColor: UIColor? {
return .clear
}
override var nx_useBlurNavigationBar: Bool {
return true
}
📝 示例代码
override var nx_shadowColor: UIColor? {
return .red
}
📝 示例代码
override var nx_shadowImage: UIImage? {
return UIImage(named: "NavigationBarShadowImage")
}
📝 示例代码
override var nx_backImage: UIImage? {
return UIImage(named: "NavigationBarBack")
}
📝 示例代码
override var nx_backButtonCustomView: UIView? {
return backButton
}
📝 示例代码
func nx_navigationTransition(_ transitionViewController: UIViewController, navigationBackAction action: NXNavigationBackAction) -> Bool {
if case .interactionGesture = action {
return false
}
return true
}
📝 示例代码
override var nx_enableFullScreenInteractivePopGesture: Bool {
return true
}
let configuration = NXNavigationConfiguration.default
configuration.viewControllerPreferences.enableFullScreenInteractivePopGesture = true
📝 示例代码
// 此操作会将导航栏的背景设置为透明、导航栏所在区域的底部能够接收到点击事件、返回按钮也将不存在。
// “隐藏”导航栏时不要添加 UINavigationBar 的 barButtonItem(s),这样就可以看起来真的像导航栏隐藏了。
// 不隐藏系统导航栏的原因是:可以让整个导航栏的过渡更加平滑自然,当然也不推荐除此之外任何隐藏系统导航栏的方式。
override var nx_translucentNavigationBar: Bool {
return true
}
📝 示例代码
override var systemNavigationBarUserInteractionDisabled: Bool {
return true
}
📝 示例代码
nx_setNeedsNavigationBarAppearanceUpdate()
如果状态栏样式没有发生变化,请检查是否需要调用方法 setNeedsStatusBarAppearanceUpdate()
,或者在 UINavigationController
的子类中设置如下代码:
override var childForStatusBarStyle: UIViewController? {
return topViewController
}
override var childForStatusBarHidden: UIViewController? {
return topViewController
}
📝 示例代码
需要遵守协议 <NXNavigationTransitionDelegate>
,实现代理方法:
NXNavigationBackActionCallingNXPopMethod
: 调用 nx_pop
系列方法返回事件拦截。NXNavigationBackActionClickBackButton
: 点击返回按钮返回事件拦截。NXNavigationBackActionClickBackButtonMenu
: 长按返回按钮选择菜单返回事件拦截。NXNavigationBackActionInteractionGesture
: 使用手势交互返回事件拦截。func nx_navigationTransition(_ transitionViewController: UIViewController, navigationBackAction action: NXNavigationBackAction) -> Bool {
switch action {
case .clickBackButton:
// Do something
return false
case .clickBackButtonMenu:
// Do something
return false
case .interactionGesture:
// Do something
return false
case .callingNXPopMethod:
// Do something
return false
default:
// Continue back
return true
}
}
自定义返回按钮事件需要拦截可以调用 nx_popViewControllerAnimated:
、nx_popToViewController:animated:
或 nx_popToRootViewControllerAnimated:
等方法来触发上面的代理回调。
需要遵守协议 <NXNavigationTransitionDelegate>
,实现代理方法:
func nx_navigationTransition(_ transitionViewController: UIViewController, navigationTransitionState state: NXNavigationTransitionState) {
switch state {
case .unspecified: print("Unspecified")
case .willPush: print("WillPush")
case .didPush: print("DidPush")
case .pushCancelled: print("PushCancelled")
case .pushCompleted: print("PushCompleted")
case .willPop: print("WillPop")
case .didPop: print("DidPop")
case .popCancelled: print("PopCancelled")
case .popCompleted: print("PopCompleted")
case .willSet: print("WillSet")
case .didSet: print("DidSet")
case .setCancelled: print("SetCancelled")
case .setCompleted: print("SetCompleted")
default: print("None")
}
}
📝 示例代码
override var nx_useSystemBackButton: Bool {
return true
}
NXNavigationExtension 框架是在 MIT 许可下发布的。详情请参见 LICENSE。
link |
Stars: 146 |
Last commit: 12 weeks ago |
代码优化
Swiftpack is being maintained by Petr Pavlik | @ptrpavlik | @swiftpackco | API | Analytics