amisare
/
NNNavigationBar
Public
-
Notifications
You must be signed in to change notification settings - Fork 43
-
Star 243
NNNavigationBar 实现导航条背景渐变过渡动画的轻量级框架
License
243
stars
43
forks
Branches
Tags
Activity
Star
Notifications
You must be signed in to change notification settings
amisare/NNNavigationBar
Branches Tags
Folders and files
Name | Name | Last commit message | Last commit date | |
---|---|---|---|---|
Latest commitHistory166 Commits | ||||
Example | Example | |||
NNNavigationBar.xcodeproj | NNNavigationBar.xcodeproj | |||
NNNavigationBar.xcworkspace | NNNavigationBar.xcworkspace | |||
NNNavigationBar | NNNavigationBar | |||
NNNavigationBarTests | NNNavigationBarTests | |||
Pods | Pods | |||
Supporting Files | Supporting Files | |||
.gitignore | .gitignore | |||
LICENSE | LICENSE | |||
NNNavigationBar.podspec | NNNavigationBar.podspec | |||
Podfile | Podfile | |||
Podfile.lock | Podfile.lock | |||
README.md | README.md | |||
Repository files navigation
本库用于实现UINavigationBar背景渐变过渡动画。
可能会遇到的问题
UINavigationBar 上的一个系统 bug ( An apple bug on the UINavigationBar)
bug 描述:导航右滑返回手势,概率性的导致返回以后页面的 rightBarButtonItem 的 tintColor 颜色变浅, bug 现象如下:
bug 代码:
- 在 viewDidLoad 中设置 rightBarButtonItem 会导致 bug 产生。bug 是概率性发生的,不易复现。
override func viewDidLoad() { super.viewDidLoad() // 在 viewDidLoad 中设置 rightBarButtonItem self.navigationItem.rightBarButtonItem = UIBarButtonItem.init(title: "Next", style: .plain, target: self, action: #selector(pushNextViewController)) self.view.backgroundColor = UIColor.white self.title = "Title" + " " + "\(self.page)" } @objc public func pushNextViewController() { let vc = self.nextViewController; vc.page = self.page + 1 self.navigationController?.pushViewController(vc, animated: true) }
bug 解决:
- 方式2:在 viewWillAppear 中设置 rightBarButtonItem 。
override func viewDidLoad() { super.viewDidLoad() // 将 rightBarButtonItem 设置移至 viewWillAppear // self.navigationItem.rightBarButtonItem = UIBarButtonItem.init(title: "Next", style: .plain, target: self, action: #selector(pushNextViewController)) self.view.backgroundColor = UIColor.white self.title = "Title" + " " + "\(self.page)" } override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) // 在 viewWillAppear 中设置 rightBarButtonItem self.navigationItem.rightBarButtonItem = UIBarButtonItem.init(title: "Next", style: .plain, target: self, action: #selector(pushNextViewController)) } @objc public func pushNextViewController() { let vc = self.nextViewController; vc.page = self.page + 1 self.navigationController?.pushViewController(vc, animated: true) }
- 方法2: issues12
bug 工程源码: UINavigationBarBug
效果
介绍
NNNavigationBar是实现导航条背景渐变过渡动画的轻量级代码库。
实现
- 代码库通过Category/Method Swizzling方式hook UINavigationBar的方法调用,实现导航条背景渐变过渡动画。
轻量
- 仅对UINavigationBar进行了Method Swizzling方法混淆。不涉及其它类的方法混淆,如UIViewController、UINavigationController等。
- 仅对UINavigationBar/UINavigationItem进行了必要的属性关联。
原理
UINavigationItem (category_xxx)
|
|
V
①
add [.nn_xxx]
| UIViewController
| -------------------> [.navigationItem]
|
|
V
②
set vcn.navigationItem.nn_xxx
|
|
|
UINavigationController V
vc stack ③
| vcn | <----- navigationController push/pop vcn
| ... | |
| vc1 | |
| vc0 | |
|
UINavigationBar |
----------------------- |
| <—— title | |
----------------------- |
| |
| UINavigationBar.Items V
| ④-② item stack ④-①
|<--- update Bar --- | vcn.navigationItem | <--- navigationBar push/pop vcn.navigationItem
| | | ... | |
| | | vc2.navigationItem | |
| | | vc1.navigationItem | |
| | | vc0.navigationItem | |
| | |
| | ④-③ |
| |---------------------> hook <-----------------------|
| |
| |
| |
| ⑤ |
|<--- update Bar [.nn_xx] -----------|
- 使用runtime在UINavigationItem的Category中添加属性[.nn_xx]。
- 每个UIViewController中都拥有一个UINavigationItem属性navigationItem,在UIViewController中修改navigationItem对象的属性[.nn_xx]。
- 在UINavigationController push/pop UIViewController时,会将UIViewController的navigationItem对象 push/pop 给UINavigationBar。
- 通过Method Swizzling方式hook UINavigationBar方法调用,获得对应方法的调用时机。
- 在合适的时刻,UINavigationBar取得navigationItem对象中的属性[.nn_xx],更新UINavigationBar状态(本代码库实现了背景的平滑渐变过渡)。
使用
- 导入头文件
#import "NNNavigationBar.h"
- 颜色渐变过渡
- (void)viewDidLoad {
[super viewDidLoad];
// 去除系统背景
[self.navigationController.navigationBar setBackgroundImage:[UIImage new] forBarMetrics:UIBarMetricsDefault];
[self.navigationController.navigationBar setShadowImage:[UIImage new]];
// 显示自定义背景
self.navigationController.navigationBar.nn_backgroundViewHidden = false;
// 设置背景颜色
self.navigationItem.nn_backgroundColor = [UIColor orangeColor];
}
- 图片渐变过渡
- (void)viewDidLoad {
[super viewDidLoad];
// 去除系统背景
[self.navigationController.navigationBar setBackgroundImage:[UIImage new] forBarMetrics:UIBarMetricsDefault];
[self.navigationController.navigationBar setShadowImage:[UIImage new]];
// 显示自定义背景
self.navigationController.navigationBar.nn_backgroundViewHidden = false;
// 设置背景图片
self.navigationItem.nn_backgroundImage = [UIImage imageNamed:xx_image];
}
- 更多使用,详见demo
安装
通过 CocoaPods 集成
安装最新版的 CocoaPods:
$ gem install cocoapods
在 podfile
中添加:
pod 'NNNavigationBar', '~> 2.7.3'
然后在终端执行:
$ pod install
如安装失败,提示:
[!] Unable to find a specification for `NNNavigationBar`
尝试使用命令:
pod install --repo-update
通过 Carthage 集成
Carthage 是一个去中心化的依赖管理器,用于构建依赖和提供二进制 Framework 。
可以通过以下 Homebrew 命令安装 Carthage :
$ brew update
$ brew install carthage
通过 Carthage 将 NNNavigationBar 集成到 Xcode 项目中,需要在 Cartfile
中添加:
github "amisare/NNNavigationBar" ~> 2.7.3
执行 carthage
构建 Framework ,并将 NNNavigationBar.framework
添加到 Xcode 项目中。
系统要求
- iOS 8.0+
鸣谢
- Logo designed by anharismail
许可证
NNNavigationBar 是基于 MIT 许可证下发布的,详情参见 LICENSE。
About
NNNavigationBar 实现导航条背景渐变过渡动画的轻量级框架
Topics
uinavigationcontroller
uinavigationitem
uinavigationbar
Resources
Readme
License
Activity
Stars
243
stars
Watchers
12
watching
Forks
43
forks
Report repository
Releases 14
2.7.3
Latest
+ 13 releases
Packages 0
No packages published
Languages
- Objective-C 66.4%
- Swift 31.8%
- Ruby 1.8%