贡献作者 -【XJDomain】
博客XJ: https://my.oschina.net/shengbingli/blog
GitHub直播地址: https://github.com/lishengbing/XJDomainLive
1:设置导航栏的背景色的三种方法:
我先说说我的做法:
XJ-----01
> 设置背景色
> 去掉那根线
> 我采用第二种,使用图片来设置背景色,这点的好处就是如果你想要更改或者去掉导航栏上的那更显的话,这种方法搭配一句即可搞定:
> 但是使用第三种方法的话,虽然设置背景色很方便,但是去掉下面的一条线的话,这句话没有效果,不太好设置
// 设置背景色
navBar.setBackgroundImage(UIImage(named: navBarBackgroundImageName ?? kBackgroundImageNameType.navBarBg_04BEC6.rawValue), for: .default)
navBar.shadowImage = UIImage()
// 通过直接设置bar上的背景色来设置导航栏上的背景色,简单粗暴,如果不是很计较那根线的话,这样设置很好
navigationBar.barTintColor = UIColor.orange
XJ-----02
> 设置导航栏线条的那根线的颜色的话:切一张图片 || 自己画一个图片也很方便的
> 任意设置frame,写了一个UIColor的分类---对象方法的得到图片,任意修改颜色和颜色的透明度
// 设置背景色
navBar.setBackgroundImage(UIImage(named: navBarBackgroundImageName ?? kBackgroundImageNameType.navBarBg_04BEC6.rawValue), for: .default)
navBar.shadowImage = UIColor.red.getImage(frame: CGRect(x: 0, y: 0, width: 1, height: 0.15))
import UIKit
extension UIColor {
convenience init(r : CGFloat, g : CGFloat, b : CGFloat) {
self.init(red: r / 255.0, green: g / 255.0, blue: b / 255.0, alpha: 1.0)
}
class func random() -> UIColor {
return UIColor(r: CGFloat(arc4random_uniform(255)), g: CGFloat(arc4random_uniform(255)), b: CGFloat(arc4random_uniform(255)))
}
func getImage(frame : CGRect) -> UIImage {
var image : UIImage!
let view = UIView(frame: frame)
view.backgroundColor = self
UIGraphicsBeginImageContext(view.frame.size)
guard let context = UIGraphicsGetCurrentContext() else {
return UIImage()
}
view.layer.render(in: context)
image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return image
}
}
XJ-----03
> 设置导航栏标题的字体大小 、颜色、等等
// 设置UIBarButtonItem上内容的字体大小
let attrs = [NSFontAttributeName : UIFont.systemFont(ofSize: 15), NSForegroundColorAttributeName : UIColor.orange]
navigationBar.titleTextAttributes = attrs
XJ-----04
> 设置返回按钮的字体颜色
// 设置返回按钮的区域之类的颜色
let navBar = UINavigationBar.appearance(whenContainedInInstancesOf: [CHNavigationController.self])
navBar.tintColor = UIColor.orange
XJ-----05
> 重写系统返回按钮:注意我这里因为项目中没有用到tabbar,所以不需要判断第一层之类的,你们懂得!!!
override func pushViewController(_ viewController: UIViewController, animated: Bool) {
viewController.navigationItem.leftBarButtonItem = UIBarButtonItem(iamgeNameNormal: "icon_4", iamgeNameHighlighted: "icon_13", target: self, action: #selector(backClick))
super.pushViewController(viewController, animated: animated)
}
@objc fileprivate func backClick() {
popViewController(animated: true)
}
XJ-----06
> 大家都知道,只要重写了系统的返回按钮的话,就会干掉系统的侧滑手势,为了解决这个问题,我的做法是:
> 干掉系统的侧滑手势,自己自定义一个手势,但是使用系统的侧滑方法即可搞定
func setupPanGes() {
guard let systemGes = interactivePopGestureRecognizer else { return }
guard let gesView = systemGes.view else { return }
let targets = systemGes.value(forKey: "_targets") as? [NSObject]
guard let targetObjc = targets?.first else { return }
guard let target = targetObjc.value(forKey: "target") else { return }
let action = Selector(("handleNavigationTransition:"))
//let screenPanGes = UIScreenEdgePanGestureRecognizer()
let pan = UIPanGestureRecognizer(target: target, action: action)
gesView.addGestureRecognizer(pan)
pan.delegate = self
self.interactivePopGestureRecognizer?.isEnabled = false
}
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool {
self.view.endEditing(true)
if childViewControllers.count == 1 {
return false
}
return true
}
XJ-----07
> 需求1: 如果项目中使用导航栏不同的背景色的话,我也是采用图片设置背景色,具体做法如下:
> 外部传参数这个控制器该显示什么背景的导航栏,但是会有默认的导航栏背景色,所以我是重写了导航栏创建方法的rootVIewController方法
var navBarBackgroundImageName : String?
init(rootViewController: UIViewController, navBarBackgroundImageName : String? = kBackgroundImageNameType.navBarBg_04BEC6.rawValue) {
super.init(nibName: nil, bundle: nil)
self.viewControllers.insert(rootViewController, at: 0)
self.navBarBackgroundImageName = navBarBackgroundImageName
let navBar = UINavigationBar.appearance(whenContainedInInstancesOf: [CHNavigationController.self])
navBar.setBackgroundImage(UIImage(named: navBarBackgroundImageName!), for: .default)
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func viewDidLoad() {
super.viewDidLoad()
setupPanGes()
}
extension UIBarButtonItem {
convenience init(iamgeNameNormal : String, iamgeNameHighlighted : String, target : Any, action : Any) {
let btn = UIButton()
btn.setImage(UIImage(named: iamgeNameNormal), for: .normal)
btn.setImage(UIImage(named: iamgeNameHighlighted), for: .highlighted)
btn.sizeToFit()
btn.contentEdgeInsets = UIEdgeInsetsMake(0, -20, 0, 0)
//btn.backgroundColor = UIColor.red
btn.addTarget(target, action: action as! Selector, for: .touchUpInside)
self.init(customView: btn)
}
convenience init(title : String, target : Any, action : Any) {
let btn = UIButton()
btn.setTitle(title, for: .normal)
btn.titleLabel?.font = UIFont.systemFont(ofSize: 13)
btn.sizeToFit()
btn.contentEdgeInsets = UIEdgeInsetsMake(0, -20, 0, 0)
//btn.backgroundColor = UIColor.red
btn.addTarget(target, action: action as! Selector, for: .touchUpInside)
self.init(customView: btn)
}
}
XJ-----08
> 注意点:切换导航栏背景色的时候,要想其他设置都有想过,不能在viewDidLoad()方法中去设置,需要在viewWillAppear(_ animated: Bool)方法中去实现
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
setupUI()
}
fileprivate func setupUI() {
// 设置返回按钮的区域之类的颜色
let navBar = UINavigationBar.appearance(whenContainedInInstancesOf: [CHNavigationController.self])
navBar.tintColor = UIColor.orange
// 设置背景色
navBar.setBackgroundImage(UIImage(named: navBarBackgroundImageName ?? kBackgroundImageNameType.navBarBg_04BEC6.rawValue), for: .default)
navBar.shadowImage = UIImage()
// 设置UIBarButtonItem上内容的字体大小
let attrs = [NSFontAttributeName : UIFont.systemFont(ofSize: 15), NSForegroundColorAttributeName : UIColor.orange]
navigationBar.titleTextAttributes = attrs
}
XJ-----09
> 侧滑手势注意点: 主要是在前一个导航栏和后一个导航栏,一个隐藏了导航栏,一个显示导航栏,这种切换的侧滑手势效果,要想多级这样切换效果很好的话,需要注意一个方法的参数:
> 第一级别: animated: false
> 第二级别: animated: animated
> 完美解决亚bug!!!!!
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
navigationController?.setNavigationBarHidden(true, animated: false)
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
navigationController?.setNavigationBarHidden(false, animated: false)
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
navigationController?.setNavigationBarHidden(true, animated: animated)
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
navigationController?.setNavigationBarHidden(false, animated: animated)
}
XJ-----010
1:如果第一级别导航栏隐藏了,第二级别显示了导航栏,这种情况的话,要想全屏手势生效,上一个页面跳转前具体操作为:
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
navigationController?.setNavigationBarHidden(true, animated: animated)
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
navigationController?.setNavigationBarHidden(false, animated: animated)
}
XJ-----011
1:如果第一级别导航栏隐藏了,第二级别继续隐藏了导航栏,这种情况的话,要想全屏手势生效,上一个页面跳转前具体操作为:
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
navigationController?.setNavigationBarHidden(true, animated: false)
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
navigationController?.setNavigationBarHidden(false, animated: false)
}
XJ-----012
1:修改非全局的标题
self.navigationController?.navigationBar.titleTextAttributes = [NSForegroundColorAttributeName : UIColor.black]
来源:oschina
链接:https://my.oschina.net/u/2684046/blog/806257