{"id":13697004,"url":"https://github.com/amisare/NNNavigationBar","last_synced_at":"2025-05-03T17:32:54.497Z","repository":{"id":62448548,"uuid":"129086931","full_name":"amisare/NNNavigationBar","owner":"amisare","description":"NNNavigationBar 实现导航条背景渐变过渡动画的轻量级框架","archived":false,"fork":false,"pushed_at":"2020-02-25T01:51:21.000Z","size":11143,"stargazers_count":243,"open_issues_count":0,"forks_count":43,"subscribers_count":12,"default_branch":"master","last_synced_at":"2024-11-09T17:43:10.981Z","etag":null,"topics":["uinavigationbar","uinavigationcontroller","uinavigationitem"],"latest_commit_sha":null,"homepage":"","language":"Objective-C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/amisare.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2018-04-11T12:01:29.000Z","updated_at":"2024-07-29T09:30:32.000Z","dependencies_parsed_at":"2022-11-01T23:17:54.531Z","dependency_job_id":null,"html_url":"https://github.com/amisare/NNNavigationBar","commit_stats":null,"previous_names":[],"tags_count":24,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/amisare%2FNNNavigationBar","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/amisare%2FNNNavigationBar/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/amisare%2FNNNavigationBar/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/amisare%2FNNNavigationBar/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/amisare","download_url":"https://codeload.github.com/amisare/NNNavigationBar/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":224369829,"owners_count":17299961,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["uinavigationbar","uinavigationcontroller","uinavigationitem"],"created_at":"2024-08-02T18:00:51.363Z","updated_at":"2024-11-13T00:31:19.124Z","avatar_url":"https://github.com/amisare.png","language":"Objective-C","readme":"\u003cp align=\"center\" \u003e\n  \u003cimg src=\"https://raw.githubusercontent.com/amisare/Logos/master/NNNavigationBar/Original/horizontal-color.png\" width=\"509\" height=\"124\" alt=\"NNNavigationBar\" title=\"NNNavigationBar\"\u003e\n\u003c/p\u003e\n\n[![GitHub release](https://img.shields.io/github/release/amisare/NNNavigationBar.svg)](https://github.com/amisare/NNNavigationBar/releases)\n[![CocoaPods](https://img.shields.io/cocoapods/v/NNNavigationBar.svg)](https://cocoapods.org/pods/NNNavigationBar)\n[![CocoaPods](https://img.shields.io/cocoapods/p/NNNavigationBar.svg)](https://cocoapods.org/pods/NNNavigationBar)\n[![GitHub license](https://img.shields.io/github/license/amisare/NNNavigationBar.svg)](https://github.com/amisare/NNNavigationBar/blob/master/LICENSE)\n\n本库用于实现UINavigationBar背景渐变过渡动画。\n\n## 可能会遇到的问题\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cmark\u003eUINavigationBar 上的一个系统 bug （ An apple bug on the UINavigationBar）\u003c/mark\u003e\u003c/summary\u003e\n\u003cp\u003e\u003c/p\u003e\n\n\u003cblockquote\u003e\n\nbug 描述：导航右滑返回手势，概率性的导致返回以后页面的 rightBarButtonItem 的 tintColor 颜色变浅， bug 现象如下：\n\n![wx20181226-142113](https://user-images.githubusercontent.com/6335968/50435206-3f2a1400-091b-11e9-9ce7-7e9ba1f10acb.png)\n\nbug 代码：\n\n- 在 viewDidLoad 中设置 rightBarButtonItem 会导致 bug 产生。bug 是概率性发生的，不易复现。\n\n```\n    override func viewDidLoad() {\n        super.viewDidLoad()\n\n        // 在 viewDidLoad 中设置 rightBarButtonItem\n        self.navigationItem.rightBarButtonItem = UIBarButtonItem.init(title: \"Next\", style: .plain, target: self, action: #selector(pushNextViewController))\n        self.view.backgroundColor = UIColor.white\n        self.title = \"Title\" + \" \" + \"\\(self.page)\"\n    }\n\n    @objc public func pushNextViewController() {\n        let vc = self.nextViewController;\n        vc.page = self.page + 1\n        self.navigationController?.pushViewController(vc, animated: true)\n    }\n```\n\nbug 解决：\n\n- 方式2：在 viewWillAppear 中设置 rightBarButtonItem 。\n\n```\n    override func viewDidLoad() {\n        super.viewDidLoad()\n        \n       // 将 rightBarButtonItem 设置移至 viewWillAppear\n       // self.navigationItem.rightBarButtonItem = UIBarButtonItem.init(title: \"Next\", style: .plain, target: self, action: #selector(pushNextViewController))\n        self.view.backgroundColor = UIColor.white\n        self.title = \"Title\" + \" \" + \"\\(self.page)\"\n    }\n    \n    override func viewWillAppear(_ animated: Bool) {\n        super.viewWillAppear(animated)\n        \n       // 在 viewWillAppear 中设置 rightBarButtonItem\n        self.navigationItem.rightBarButtonItem = UIBarButtonItem.init(title: \"Next\", style: .plain, target: self, action: #selector(pushNextViewController))\n    }\n    \n    @objc public func pushNextViewController() {\n        let vc = self.nextViewController;\n        vc.page = self.page + 1\n        self.navigationController?.pushViewController(vc, animated: true)\n    }\n```\n\n- 方法2：[issues12](https://github.com/amisare/NNNavigationBar/issues/12)\n\nbug 工程源码：[UINavigationBarBug](https://github.com/amisare/UINavigationBarBug)\n\n\u003c/blockquote\u003e\n\u003c/details\u003e\n\n\n## 效果\n\n![ColorTransition](https://raw.githubusercontent.com/amisare/Screenshots/master/NNNavigationBar/Screenshots_00.gif)\n![ImageTransition](https://raw.githubusercontent.com/amisare/Screenshots/master/NNNavigationBar/Screenshots_01.gif)\n\n## 介绍\n\nNNNavigationBar是实现导航条背景渐变过渡动画的轻量级代码库。\n\n#### 实现\n\n- 代码库通过Category/Method Swizzling方式hook UINavigationBar的方法调用，实现导航条背景渐变过渡动画。\n\n#### 轻量\n\n- 仅对UINavigationBar进行了Method Swizzling方法混淆。不涉及其它类的方法混淆，如UIViewController、UINavigationController等。\n- 仅对UINavigationBar/UINavigationItem进行了必要的属性关联。\n\n#### 原理\n         \n```\n\n\n                              UINavigationItem (category_xxx)\n                                           |\n                                           |\n                                           V\n                                           ①  \n                                     add [.nn_xxx]\n                                           |                         UIViewController\n                                           |  -------------------\u003e  [.navigationItem]\n                                                                             |\n                                                                             |\n                                                                             V\n                                                                             ② \n                                                               set vcn.navigationItem.nn_xxx\n                                                                             |\n                                                                             |\n                                                                             |\n                                 UINavigationController                      V\n                                       vc stack                              ③            \n                                 |        vcn        | \u003c----- navigationController push/pop vcn\n                                 |        ...        |                       |\n                                 |        vc1        |                       |\n                                 |        vc0        |                       |          \n                                                                             |\n     UINavigationBar                                                         |\n-----------------------                                                      |\n| \u003c——    title        |                                                      |\n-----------------------                                                      |\n           |                                                                 |\n           |                     UINavigationBar.Items                       V\n           |        ④-②              item stack                           ④-①\n           |\u003c--- update Bar --- | vcn.navigationItem | \u003c--- navigationBar push/pop vcn.navigationItem\n           |          |         |        ...         |                       |\n           |          |         | vc2.navigationItem |                       |\n           |          |         | vc1.navigationItem |                       |\n           |          |         | vc0.navigationItem |                       |\n           |          |                                                      |\n           |          |                        ④-③                          |\n           |          |---------------------\u003e  hook  \u003c-----------------------|\n           |                                    |\n           |                                    |\n           |                                    |\n           |             ⑤                     |\n           |\u003c--- update Bar [.nn_xx] -----------|\n                                                      \n```\n\n1. 使用runtime在UINavigationItem的Category中添加属性[.nn_xx]。\n2. 每个UIViewController中都拥有一个UINavigationItem属性navigationItem，在UIViewController中修改navigationItem对象的属性[.nn_xx]。\n3. 在UINavigationController push/pop UIViewController时，会将UIViewController的navigationItem对象 push/pop 给UINavigationBar。\n4. 通过Method Swizzling方式hook UINavigationBar方法调用，获得对应方法的调用时机。\n5. 在合适的时刻，UINavigationBar取得navigationItem对象中的属性[.nn_xx]，更新UINavigationBar状态（本代码库实现了背景的平滑渐变过渡）。\n\n## 使用\n\n1. 导入头文件\n\n```\n#import \"NNNavigationBar.h\"\n```\n\n2. 颜色渐变过渡\n\n```\n- (void)viewDidLoad {\n    [super viewDidLoad];\n    // 去除系统背景\n    [self.navigationController.navigationBar setBackgroundImage:[UIImage new] forBarMetrics:UIBarMetricsDefault];\n    [self.navigationController.navigationBar setShadowImage:[UIImage new]];\n    // 显示自定义背景\n    self.navigationController.navigationBar.nn_backgroundViewHidden = false;\n    // 设置背景颜色\n    self.navigationItem.nn_backgroundColor = [UIColor orangeColor];\n}\n```\n\n3. 图片渐变过渡\n\n```\n- (void)viewDidLoad {\n    [super viewDidLoad];\n    // 去除系统背景\n    [self.navigationController.navigationBar setBackgroundImage:[UIImage new] forBarMetrics:UIBarMetricsDefault];\n    [self.navigationController.navigationBar setShadowImage:[UIImage new]];\n    // 显示自定义背景\n    self.navigationController.navigationBar.nn_backgroundViewHidden = false;\n    // 设置背景图片\n    self.navigationItem.nn_backgroundImage = [UIImage imageNamed:xx_image];\n}\n```\n\n4. 更多使用，详见demo\n\n\n## 安装\n\n### 通过 CocoaPods 集成\n\n安装最新版的 CocoaPods：\n\n```bash\n$ gem install cocoapods\n```\n\n在 `podfile` 中添加：\n\n```ruby\npod 'NNNavigationBar', '~\u003e 2.7.3'\n```\n\n然后在终端执行：\n\n```bash\n$ pod install\n```\n\n如安装失败，提示：\n\n```bash\n[!] Unable to find a specification for `NNNavigationBar`\n```\n\n尝试使用命令：\n\n```bash\npod install --repo-update\n```\n\n### 通过 Carthage 集成\n\n[Carthage](https://github.com/Carthage/Carthage) 是一个去中心化的依赖管理器，用于构建依赖和提供二进制 Framework 。\n\n可以通过以下 [Homebrew](http://brew.sh/) 命令安装 Carthage ：\n\n```bash\n$ brew update\n$ brew install carthage\n```\n\n通过 Carthage 将 NNNavigationBar 集成到 Xcode 项目中，需要在 `Cartfile` 中添加：\n\n```ogdl\ngithub \"amisare/NNNavigationBar\" ~\u003e 2.7.3\n```\n\n执行 `carthage` 构建 Framework ，并将 `NNNavigationBar.framework` 添加到 Xcode 项目中。\n\n## 系统要求\n\n- iOS 8.0+\n\n## 鸣谢\n\n- Logo designed by [anharismail](https://github.com/anharismail)\n\n## 许可证\n\nNNNavigationBar 是基于 MIT 许可证下发布的，详情参见 LICENSE。\n","funding_links":[],"categories":["UI Effects","OOM-Leaks-Crash"],"sub_categories":["Navigation"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Famisare%2FNNNavigationBar","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Famisare%2FNNNavigationBar","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Famisare%2FNNNavigationBar/lists"}