通过枚举提供灵活多样的导航栏样式,设置所需属性快速实现自定义效果,整体通过扩展的方式添加属性能够实现快速对接,同样适配iOS15
通过本篇文章您可以使用Swift实现以下的导航栏效果
1.自定义导航栏背景图片;
2.自定义标题颜色;
3.设置APP的默认主色调;
4.导航栏透明样式;
5.导航栏隐藏
支持的导航栏样式
//MARK: - 定义导航栏样式
enum NavigationBarStyle {
///navbar APP主题(需要设置自己APP的主色调)
case theme
///navbar 透明
case transparent
///navbar 白色的
case white
///跟随黑暗模式的导航栏
case autoWhite
case customImg(navBgImage:UIImage? = nil,//导航背景图
navTitleTextColor:UIColor? = .a_blackText_color,//导航标题字体色
navStatusBarStyle:UIStatusBarStyle? = .default)//导航状态栏字体色
///自定义导航栏
case custom(navBgColor:UIColor? = .a_whiteNavBg_color,//导航背景色
navBgImage:UIImage? = nil,//导航背景图
navTitleTextColor:UIColor? = .a_blackText_color,//导航标题字体色
navStatusBarStyle:UIStatusBarStyle? = .default,//导航状态栏字体色
navShadowColor:UIColor? = nil,//导航bottom line 色
navTintColor:UIColor? = .a_black_color,//导航 item 颜色
navIsTranslucent:Bool? = false)//是否透明
///navbar 隐藏
//UIStatusBarStyle
case hidden(statusBarStyle:UIStatusBarStyle = .lightContent,barStyle:UIBarStyle? = .default)
}
通过扩展直接设置导航栏样式
//MARK: - 设置导航栏样式
extension BaseNavigationController {
private struct AssociatedGestureKeys {
static var disablePopGesture:Void?
}
///侧滑返回权限限制, 默认false不限制
var disablePopGesture:Bool {
get {
return objc_getAssociatedObject(self, &AssociatedGestureKeys.disablePopGesture) as? Bool ?? false
}
set {
objc_setAssociatedObject(self, &AssociatedGestureKeys.disablePopGesture,newValue,.OBJC_ASSOCIATION_RETAIN_NONATOMIC)
}
}
private struct AssociatedNavBarAppearanceKeys {
static var navBarAppearance:Void?
}
@available(iOS 13.0, *)
var navBarAppearance:UINavigationBarAppearance{
get{
return objc_getAssociatedObject(self, &AssociatedNavBarAppearanceKeys.navBarAppearance) as? UINavigationBarAppearance ?? navigationBar.standardAppearance
}
set {
objc_setAssociatedObject(self, &AssociatedNavBarAppearanceKeys.navBarAppearance,newValue,.OBJC_ASSOCIATION_RETAIN_NONATOMIC)
}
}
func navBarStyle(style:NavigationBarStyle,animated:Bool = false) {
switch style {
case .theme:
setNavigationBarHidden(false, animated: animated)
navigationBar.barStyle = .default
self.myStatusBarStyle = .default
//self.navBarBgColor = .white
//self.navTitleColor = UIColor.black
let attrDic = [NSAttributedString.Key.foregroundColor:UIColor.black,
NSAttributedString.Key.font:UIFont.systemFont(ofSize: 18.0)]
let navBgImg = UIImage(named:"nav_bg")!.withRenderingMode(.alwaysOriginal)
if #available(iOS 13.0, *) {
let barApp = self.navBarAppearance
barApp.backgroundColor = .white
barApp.backgroundImage = navBgImg
//基于backgroundColor或backgroundImage的磨砂效果
barApp.backgroundEffect = nil
barApp.shadowImage = UIImage()
//阴影颜色(底部分割线),当shadowImage为nil时,直接使用此颜色为阴影色。如果此属性为nil或clearColor(需要显式设置),则不显示阴影。
barApp.shadowColor = nil;
//标题文字颜色
barApp.titleTextAttributes = attrDic
navigationBar.scrollEdgeAppearance = barApp
navigationBar.standardAppearance = barApp
}else {
navigationBar.titleTextAttributes = attrDic
navigationBar.shadowImage = UIImage()
navigationBar.setBackgroundImage(navBgImg, for: .default)
}
//透明设置
navigationBar.isTranslucent = false;
//navigationItem控件的颜色
navigationBar.tintColor = .white
_navBarBgColor = .white
case .transparent:
setNavigationBarHidden(false, animated: animated)
navigationBar.barStyle = .default
self.myStatusBarStyle = .default
//self.navBarBgColor = .clear
//self.navTitleColor = UIColor.white
let attrDic = [NSAttributedString.Key.foregroundColor: UIColor.white,
NSAttributedString.Key.font: UIFont.systemFont(ofSize: 18.0)]
if #available(iOS 13.0, *) {
let barApp = self.navBarAppearance
barApp.backgroundColor = .clear
barApp.backgroundImage = nil
//基于backgroundColor或backgroundImage的磨砂效果
barApp.backgroundEffect = nil
barApp.shadowImage = UIImage()
//阴影颜色(底部分割线),当shadowImage为nil时,直接使用此颜色为阴影色。如果此属性为nil或clearColor(需要显式设置),则不显示阴影。
barApp.shadowColor = nil;
//标题文字颜色
barApp.titleTextAttributes = attrDic
navigationBar.scrollEdgeAppearance = nil
navigationBar.standardAppearance = barApp
}else {
navigationBar.titleTextAttributes = attrDic
navigationBar.shadowImage = UIImage()
let navBgImg = UIImage.imgColor(UIColor.clear, CGSize(width: SCREEN_WIDTH, height: MYLayout.kNav_Height)).withRenderingMode(.alwaysOriginal)
navigationBar.backgroundColor = .clear
navigationBar.setBackgroundImage(navBgImg, for: .default)
}
//透明设置
navigationBar.isTranslucent = true;
_navBarBgColor = .clear
//navigationItem控件的颜色
//navigationBar.tintColor = .white
LLog("都有啥######:\(navigationBar.subviews)")
case .white:
setNavigationBarHidden(false, animated: animated)
navigationBar.barStyle = .black
self.myStatusBarStyle = .default
//self.navBarBgColor = .white
//self.navTitleColor = UIColor.black
let attrDic = [NSAttributedString.Key.foregroundColor: UIColor.black,
NSAttributedString.Key.font: UIFont.systemFont(ofSize: 18)]
if #available(iOS 13.0, *) {
let barApp = self.navBarAppearance
barApp.backgroundColor = .white
barApp.backgroundImage = nil
//基于backgroundColor或backgroundImage的磨砂效果
barApp.backgroundEffect = nil
barApp.shadowImage = UIImage()
//阴影颜色(底部分割线),当shadowImage为nil时,直接使用此颜色为阴影色。如果此属性为nil或clearColor(需要显式设置),则不显示阴影。
barApp.shadowColor = nil;
//标题文字颜色
barApp.titleTextAttributes = attrDic
navigationBar.scrollEdgeAppearance = barApp
navigationBar.standardAppearance = barApp
}else {
navigationBar.titleTextAttributes = attrDic
let navBgImg = UIImage.imgColor(UIColor.white, CGSize(width: SCREEN_WIDTH, height: MYLayout.kNav_Height)).withRenderingMode(.alwaysOriginal)
navigationBar.shadowImage = UIImage()
navigationBar.backgroundColor = .white
navigationBar.setBackgroundImage(navBgImg, for: .default)
}
//透明设置
navigationBar.isTranslucent = false;
//navigationItem控件的颜色
navigationBar.tintColor = .black
_navBarBgColor = .white
case .autoWhite:
setNavigationBarHidden(false, animated: animated)
navigationBar.barStyle = .default
self.myStatusBarStyle = .default
//self.navBarBgColor = .a_whiteNavBg_color
//self.navTitleColor = UIColor.a_blackText_color
let attrDic = [NSAttributedString.Key.foregroundColor:UIColor.a_blackText_color,
NSAttributedString.Key.font: UIFont.systemFont(ofSize: 18)]
let navBg_color:UIColor = .a_whiteNavBg_color
if #available(iOS 13.0, *) {
let barApp = self.navBarAppearance
barApp.backgroundColor = navBg_color
barApp.backgroundImage = nil
//基于backgroundColor或backgroundImage的磨砂效果
barApp.backgroundEffect = nil
barApp.shadowImage = UIImage()
//阴影颜色(底部分割线),当shadowImage为nil时,直接使用此颜色为阴影色。如果此属性为nil或clearColor(需要显式设置),则不显示阴影。
barApp.shadowColor = nil;
//标题文字颜色
barApp.titleTextAttributes = attrDic
navigationBar.scrollEdgeAppearance = barApp
navigationBar.standardAppearance = barApp
}else {
navigationBar.titleTextAttributes = attrDic
let navBgImg = UIImage.imgColor(navBg_color, CGSize(width: SCREEN_WIDTH, height: MYLayout.kNav_Height)).withRenderingMode(.alwaysOriginal)
navigationBar.shadowImage = UIImage()
navigationBar.backgroundColor = navBg_color
navigationBar.setBackgroundImage(navBgImg, for: .default)
}
//透明设置
navigationBar.isTranslucent = false;
//navigationItem控件的颜色
navigationBar.tintColor = .a_black_color
_navBarBgColor = navBg_color
case .hidden(let statusStyle,let barStyle):
setNavigationBarHidden(true, animated: animated)
self.myStatusBarStyle = statusStyle
navigationBar.barStyle = barStyle ?? .default
_navBarBgColor = .clear
case .customImg(let navBgImg,
let titleColor,
let statusStyle):
setNavigationBarHidden(false, animated: animated)
navigationBar.barStyle = .default
self.myStatusBarStyle = statusStyle
//self.navBarBgColor = .white
//self.navTitleColor = UIColor.black
_navBgImg = navBgImg
let attrDic = [NSAttributedString.Key.foregroundColor:titleColor ?? .a_blackText_color,
NSAttributedString.Key.font: UIFont.systemFont(ofSize: 18)]
let navBgImg = (navBgImg ?? UIImage.imgColor(.a_whiteNavBg_color, CGSize(width: SCREEN_WIDTH, height: MYLayout.kNav_Height))).withRenderingMode(.alwaysOriginal)
if #available(iOS 13.0, *) {
let barApp = self.navBarAppearance
barApp.backgroundColor = .white
barApp.backgroundImage = navBgImg
//基于backgroundColor或backgroundImage的磨砂效果
barApp.backgroundEffect = nil
barApp.shadowImage = UIImage()
//阴影颜色(底部分割线),当shadowImage为nil时,直接使用此颜色为阴影色。如果此属性为nil或clearColor(需要显式设置),则不显示阴影。
barApp.shadowColor = nil;
//标题文字颜色
barApp.titleTextAttributes = attrDic
navigationBar.scrollEdgeAppearance = barApp
navigationBar.standardAppearance = barApp
}else {
navigationBar.titleTextAttributes = attrDic
navigationBar.shadowImage = UIImage()
navigationBar.setBackgroundImage(navBgImg, for: .default)
}
//透明设置
navigationBar.isTranslucent = false;
//navigationItem控件的颜色
navigationBar.tintColor = .white
_navBarBgColor = .white
case .custom(let navBgColor,
let navBgImg,
let titleColor,
let statusStyle,
let navShadowColor,
let navTintColor,
let navIsTranslucent):
setNavigationBarHidden(false, animated: animated)
navigationBar.barStyle = .default
self.myStatusBarStyle = statusStyle
//self.navBarBgColor = .a_whiteNavBg_color
//self.navTitleColor = UIColor.a_blackText_color
_navBgImg = navBgImg
let attrDic = [NSAttributedString.Key.foregroundColor:titleColor ?? .a_blackText_color,
NSAttributedString.Key.font: UIFont.systemFont(ofSize: 18)]
let navBg_color:UIColor = navBgColor ?? .a_whiteNavBg_color
let navBgImg = (navBgImg ?? UIImage.imgColor(navBg_color, CGSize(width: SCREEN_WIDTH, height: MYLayout.kNav_Height))).withRenderingMode(.alwaysOriginal)
if #available(iOS 13.0, *) {
let barApp = self.navBarAppearance
barApp.backgroundColor = navBg_color
barApp.backgroundImage = navBgImg
//基于backgroundColor或backgroundImage的磨砂效果
barApp.backgroundEffect = nil
barApp.shadowImage = UIImage()
//阴影颜色(底部分割线),当shadowImage为nil时,直接使用此颜色为阴影色。如果此属性为nil或clearColor(需要显式设置),则不显示阴影。
barApp.shadowColor = navShadowColor
//标题文字颜色
barApp.titleTextAttributes = attrDic
navigationBar.scrollEdgeAppearance = barApp
navigationBar.standardAppearance = barApp
}else {
navigationBar.titleTextAttributes = attrDic
//let navBgImg = UIImage.imgColor(navBg_color, CGSize(width: SCREEN_WIDTH, height: MYLayout.kNav_Height)).withRenderingMode(.alwaysOriginal)
navigationBar.shadowImage = UIImage()
navigationBar.backgroundColor = navBg_color
navigationBar.setBackgroundImage(navBgImg, for: .default)
}
//透明设置
navigationBar.isTranslucent = navIsTranslucent ?? false;
//navigationItem控件的颜色
navigationBar.tintColor = navTintColor
_navBarBgColor = navBg_color
}
}
//MARK: - 增加导航栏背景色属性
private struct AssociatedNavBarBgColorKeys {
static var navBarBgColor:Void?
}
var navBarBgColor:UIColor {
get {
return objc_getAssociatedObject(self, &AssociatedNavBarBgColorKeys.navBarBgColor) as! UIColor
}
set {
let navBgColor = newValue
let navBgImg = _navBgImg ?? UIImage.imgColor(navBgColor, CGSize(width: SCREEN_WIDTH, height: MYLayout.kNav_Height)).withRenderingMode(.alwaysOriginal)//用这种方式处理过的图片添加在标签中,就可以显示图片原本的颜色;
if #available(iOS 13.0, *) {
let barApp = self.navBarAppearance
barApp.backgroundColor = navBgColor
barApp.backgroundImage = navBgImg
//barApp.backgroundEffect = [UIBlurEffect effectWithStyle:UIBlurEffectStyleRegular];
barApp.backgroundEffect = nil;//基于backgroundColor或backgroundImage的磨砂效果
//barApp.shadowColor = nil;//阴影颜色(底部分割线),当shadowImage为nil时,直接使用此颜色为阴影色。如果此属性为nil或clearColor(需要显式设置),则不显示阴影。
navigationBar.scrollEdgeAppearance = barApp;
navigationBar.standardAppearance = barApp;
}else {
navigationBar.backgroundColor = navBgColor;
navigationBar.setBackgroundImage(navBgImg, for: .default)
}
_navBarBgColor = navBgColor
//objc_setAssociatedObject(self, &AssociatedNavBarTintColorKeys.navBarTintColor, tintColor, .OBJC_ASSOCIATION_COPY)
return objc_setAssociatedObject(self, &AssociatedNavBarBgColorKeys.navBarBgColor, navBgColor, .OBJC_ASSOCIATION_COPY)
}
}
//MARK: - 增加导航栏标题字体颜色属性
private struct AssociatedNavTitleColorKeys {
static var navBarTitleColor:Void?
}
var navTitleColor:UIColor {
get {
return objc_getAssociatedObject(self, &AssociatedNavTitleColorKeys.navBarTitleColor) as! UIColor
}
set {
let titleColor = newValue
let attrDic = [NSAttributedString.Key.foregroundColor:titleColor,
NSAttributedString.Key.font: UIFont.systemFont(ofSize: 18)]
if #available(iOS 13.0, *) {
let barApp = self.navBarAppearance
barApp.titleTextAttributes = attrDic
barApp.backgroundEffect = nil;//基于backgroundColor或backgroundImage的磨砂效果
navigationBar.scrollEdgeAppearance = barApp;
navigationBar.standardAppearance = barApp;
}else {
navigationBar.titleTextAttributes = attrDic
}
return objc_setAssociatedObject(self, &AssociatedNavTitleColorKeys.navBarTitleColor, titleColor, .OBJC_ASSOCIATION_COPY)
}
}
}
调用示例
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
navigationItem.title = "设置"
//设置导航栏样式
//myNavigationController?.navBarStyle(style: .custom(navBgColor: .red), animated:animated)
myNavigationController?.navBarStyle(style: .customImg(navBgImage: .imgName("nav_bg_purple"),
navTitleTextColor: .a_whiteText_color,
navStatusBarStyle: .lightContent))
//myNavigationController?.navBarStyle(style: .theme)
//myNavigationController?.navBarStyle(style: .theme,animated:animated)
//导航标题颜色
myNavigationController?.navTitleColor = .theme_color
}
效果
上一篇:Object-C版本导航栏适配详解>>
下一篇:Swift版导航栏适配基础版>>