Giter Site home page Giter Site logo

wangrui460 / wrnavigationbar_swift Goto Github PK

View Code? Open in Web Editor NEW
635.0 14.0 92.0 59.21 MB

WRNavigationBar which allows you to change NavigationBar's appearance dynamically

License: MIT License

Swift 99.92% Ruby 0.08%
navigationbar qq navigation navigationcontroller alpha swift ltnavigationbar blkflexibleheightbar tlyshynavbar statusbar

wrnavigationbar_swift's Introduction

image

For Objective-C:https://github.com/wangrui460/WRNavigationBar


iOS 技术交流

我创建了一个 微信 iOS 技术交流群,欢迎小伙伴们加入一起交流学习~

可以加我微信我拉你进去(备注iOS),我的微信号 wr1204607318

Requirements

  • iOS 8+
  • Xcode 8+

Demo

导航栏显示渐变色

导航栏显示图片

新浪微博个人中心

qq空间

知乎日报

QQ我的资料页

蚂蚁森林

连续多个界面导航栏透明

自定义导航栏

移动导航栏

Installation

手动拖入 将 WRNavigationBar 文件夹拽入项目中即可使用

How To Use

具体使用方法请参考Demo


// 一行代码搞定导航栏颜色
navBarBarTintColor = .white
// 一行代码搞定导航栏透明度
navBarBackgroundAlpha = alpha
// 一行代码搞定导航栏两边按钮颜色
navBarTintColor = UIColor(red: 0, green: 0.478431, blue: 1, alpha: 1.0)
// 一行代码搞定导航栏上标题颜色
navBarTitleColor = .black
// 一行代码搞定状态栏是 default 还是 lightContent
statusBarStyle = .default
// 一行代码搞定导航栏底部分割线是否隐藏
navBarShadowImageHidden = true;

// 设置导航栏默认的背景颜色
UIColor.defaultNavBarBarTintColor = UIColor.init(red: 0/255.0, green: 175/255.0, blue: 240/255.0, alpha: 1)
// 设置导航栏所有按钮的默认颜色
UIColor.defaultNavBarTintColor = .white
// 设置导航栏标题默认颜色
UIColor.defaultNavBarTitleColor = .white
// 统一设置状态栏样式
UIColor.defaultStatusBarStyle = .lightContent
// 如果需要设置导航栏底部分割线隐藏,可以在这里统一设置
UIColor.defaultShadowImageHidden = true

See detail

我的简书: 韦德460

Update

  • 2017.12.09 解决问题:解决导航栏颜色和标题颜色改变失败的bug

  • 2017.12.09 解决问题:解决点击返回按钮导航栏标题颜色闪烁的问题

  • 2017.11.29- 更新:解决部分用户设置导航栏无效的问题~

  • 2017.11.29- 更新:支持自定义导航栏~

  • 2017.11.25 更新:更新到 Swift 4,适配iOS 11、iPhone X,自定义导航栏再等两天~

  • 2017.07.22 添加新DEMO:连续多个界面导航栏透明

  • 2017.07.09 解决问题:当一个控制器中包含多个控制器时,导航栏颜色或透明度不正常的问题

  • 2017.07.04 添加新功能:全局设置导航栏显示图片(不建议在非自定义导航栏中使用)

  • 2017.07.01 添加新功能:导航栏可显示图片

  • 2017.06.29 添加新功能:可单独设置每个控制器对应导航栏底部分割线是否隐藏

  • 2017.06.29 解决问题:解决引入WRNavigationBar后,无法设置导航栏标题大小的问题

  • 2017.06.19 解决问题:解决移动导航栏后右滑返回中途取消导致的导航栏错位的问题

  • 2017.06.15 解决问题:解决scrollView正在滑动的时候,点击返回按钮,导航栏颜色变化突兀的问题

  • 2017.05.21 解决问题:解决push导航栏没有渐变动画太突兀的问题

  • 2017.05.20 解决问题:解决侧滑返回导航栏没有渐变动画太突兀的**问题

  • 2017.05.16 新增Demo:完成自定义导航栏实现透明渐变等效果

  • 2017.05.12 解决问题:侧滑一点松开透明的导航栏会变不透明

License

WRNavigationBar is available under the MIT license. See the LICENSE file for more info.

wrnavigationbar_swift's People

Contributors

wangrui460 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

wrnavigationbar_swift's Issues

启动时间影响

// 1. 定义 WRAwakeProtocol 协议
public protocol WRAwakeProtocol: class {
static func wrAwake()
}
public protocol WRFatherAwakeProtocol: class
{ // 1.1 定义 WRFatherAwakeProtocol ()
static func fatherAwake()
}

class NothingToSeeHere
{
static func harmlessFunction(){
let typeCount = Int(objc_getClassList(nil, 0))
let types = UnsafeMutablePointer<AnyClass?>.allocate(capacity: typeCount)
let autoreleaseintTypes = AutoreleasingUnsafeMutablePointer(types)
objc_getClassList(autoreleaseintTypes, Int32(typeCount)) //获取所有的类
for index in 0 ..< typeCount {
(types[index] as? WRAwakeProtocol.Type)?.wrAwake() //如果该类实现了SelfAware协议,那么调用 awake 方法
(types[index] as? WRFatherAwakeProtocol.Type)?.fatherAwake()
}
types.deallocate(capacity: typeCount)
}
}

// 2. 让APP启动时只执行一次 harmlessFunction 方法
extension UIApplication
{
private static let runOnce:Void = { //使用静态属性以保证只调用一次(该属性是个方法)
NothingToSeeHere.harmlessFunction()
}()

open override var next: UIResponder?{ //重写next属性
    UIApplication.runOnce
    return super.next
}

}

这段代码,会增加APP的启动时间,严重影响了APP启动时间

initialize()

Method 'initialize()' defines Objective-C class method 'initialize', which is not guaranteed to be invoked by Swift and will be disallowed in future versions

EFNavigationBar

迫于本项目目前较多 Bug 且长期无人维护,遂基于 WRNavigationBar_swift 代码建立了项目 EFNavigationBar,可由 WRNavigationBar_swift 无缝切换,且支持通过 CocoaPods 进行依赖,目前已发布 0.1.0 版本,欢迎有需求的同学使用和提意见,感兴趣的同学也可共同参与开发 / 维护工作。

同时在此对 WRNavigationBar_swift 原作者 wangrui460 所做的工作表示感谢。

HZNavigationBar

高度自定义的NavigationBar,灵感来自于WRNavigationBar作者,目前HZNavigationBar已稳定运行于自己公司项目一年多,满足绝大多数的导航栏需求

显示异常

swift版本,iOS 11上,导航栏显示都异常。
自定义导航栏tab,点击主页,闪退。

xcode9 ios11一系列问题、

每次进入透明导航页面,都没有透明,必须滑动一下才能透明,当点击详情页的cell进入下个页面后,侧滑回来导航栏又显示了。
自定义导航栏直接crash
移动导航栏自定义返回按钮的界面也有些许问题。。。

navBarBackgroundAlpha is not working

Hey,

If you are trying to use navBarBackgroundAlpha = 0 but giving white background and you want to use imageView example your have to use

navigationController?.navigationBar.isTranslucent = true

Thanks

通话的时候打开APP,全局配置 导航栏按钮颜色的方法无效

通话的时候打开APP,全局配置 导航栏按钮颜色的方法无效

在didFinishLaunchingWithOptions中设置

// 设置导航栏默认的背景颜色 WRNavigationBar.defaultNavBarBarTintColor = UIColor.white // 设置导航栏所有按钮的默认颜色 WRNavigationBar.defaultNavBarTintColor = BASE_COLOR // 设置导航栏标题默认颜色 WRNavigationBar.defaultNavBarTitleColor = BASE_COLOR // 统一设置状态栏样式 WRNavigationBar.defaultStatusBarStyle = .default // 如果需要设置导航栏底部分割线隐藏,可以在这里统一设置 WRNavigationBar.defaultShadowImageHidden = true

在UITableViewController中与UIRefreshControl共用有bug

override func viewDidLoad() {
    refreshControl = UIRefreshControl.init()
    navBarBackgroundAlpha = 0
}
    private func changeNavBarAnimateWithIsClear(isClear:Bool)
    {
        UIView.animate(withDuration: 0.5, animations: { [weak self] in
            if let weakSelf = self
            {
                if (isClear == true) {
                    weakSelf.navBarBackgroundAlpha = 0
                }
                else {
                    weakSelf.navBarBackgroundAlpha = 1.0
                }
            }
        })
    }

changeNavBarAnimateWithIsClear(isClear: false)
后面任意时间调用不会显示NavigationBar,将refreshControl初始化部分放到viewDidAppear中就没有这个问题。

  • 手势右划翻页距离不够长时放开后title动画太突兀,作为强迫症有些难过。

  • 在使用ActionSheet后有时NavigationBar又会变成非透明,重现为push进另外一个ViewController,然后pop回来,这时候弹出ActionSheet必定变为非透明。

Swift 版本增加黑名单功能

`//
// WRNavigationBar.swift
// WRNavigationBar_swift
//
// Created by wangrui on 2017/4/19.
// Copyright © 2017年 wangrui. All rights reserved.
//
// Github地址:https://github.com/wangrui460/WRNavigationBar_swift
import UIKit

extension UINavigationBar:WRAwakeProtocol
{
fileprivate struct AssociatedKeys {
static var backgroundView: UIView = UIView()
static var backgroundImageView: UIImageView = UIImageView()
}

fileprivate var backgroundView:UIView? {
    get {
        guard let bgView = objc_getAssociatedObject(self, &AssociatedKeys.backgroundView) as? UIView else {
            return nil
        }
        return bgView
    }
    set {
        objc_setAssociatedObject(self, &AssociatedKeys.backgroundView, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
    }
}

fileprivate var backgroundImageView:UIImageView? {
    get {
        guard let bgImageView = objc_getAssociatedObject(self, &AssociatedKeys.backgroundImageView) as? UIImageView else {
            return nil
        }
        return bgImageView
    }
    set {
        objc_setAssociatedObject(self, &AssociatedKeys.backgroundImageView, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
    }
}

// set navigationBar backgroundImage
fileprivate func wr_setBackgroundImage(image:UIImage)
{
    backgroundView?.removeFromSuperview()
    backgroundView = nil
    if (backgroundImageView == nil)
    {
        // add a image(nil color) to _UIBarBackground make it clear
        setBackgroundImage(UIImage(), for: .default)
        backgroundImageView = UIImageView(frame: CGRect(x: 0, y: 0, width: Int(bounds.width), height: WRNavigationBar.navBarBottom()))
        backgroundImageView?.autoresizingMask = .flexibleWidth
        // _UIBarBackground is first subView for navigationBar
        subviews.first?.insertSubview(backgroundImageView ?? UIImageView(), at: 0)
    }
    backgroundImageView?.image = image
}

// set navigationBar barTintColor
fileprivate func wr_setBackgroundColor(color:UIColor)
{
    // 注释掉,不然导航栏会闪一下
    backgroundImageView?.removeFromSuperview()
    backgroundImageView = nil
    if (backgroundView == nil)
    {
        // add a image(nil color) to _UIBarBackground make it clear
        setBackgroundImage(UIImage(), for: .default)
        backgroundView = UIView(frame: CGRect(x: 0, y: 0, width: Int(bounds.width), height: WRNavigationBar.navBarBottom()))
        backgroundView?.autoresizingMask =  .flexibleWidth
        // _UIBarBackground is first subView for navigationBar
        subviews.first?.insertSubview(backgroundView ?? UIView(), at: 0)
    }
    backgroundView?.backgroundColor = color
}

// set _UIBarBackground alpha (_UIBarBackground subviews alpha <= _UIBarBackground alpha)
fileprivate func wr_setBackgroundAlpha(alpha:CGFloat)
{
    if let barBackgroundView = subviews.first
    {
        if #available(iOS 11.0, *)
        {   // sometimes we can't change _UIBarBackground alpha
            for view in barBackgroundView.subviews {
                view.alpha = alpha
            }
        } else {
            barBackgroundView.alpha = alpha
        }
    }
}

// 设置导航栏所有BarButtonItem的透明度
func wr_setBarButtonItemsAlpha(alpha:CGFloat, hasSystemBackIndicator:Bool)
{
    for view in subviews
    {
        if (hasSystemBackIndicator == true)
        {
            // _UIBarBackground/_UINavigationBarBackground对应的view是系统导航栏,不需要改变其透明度
            if let _UIBarBackgroundClass = NSClassFromString("_UIBarBackground")
            {
                if view.isKind(of: _UIBarBackgroundClass) == false {
                    view.alpha = alpha
                }
            }
            
            if let _UINavigationBarBackground = NSClassFromString("_UINavigationBarBackground")
            {
                if view.isKind(of: _UINavigationBarBackground) == false {
                    view.alpha = alpha
                }
            }
        }
        else
        {
            // 这里如果不做判断的话,会显示 backIndicatorImage(系统返回按钮)
            if let _UINavigationBarBackIndicatorViewClass = NSClassFromString("_UINavigationBarBackIndicatorView"),
                view.isKind(of: _UINavigationBarBackIndicatorViewClass) == false
            {
                if let _UIBarBackgroundClass = NSClassFromString("_UIBarBackground")
                {
                    if view.isKind(of: _UIBarBackgroundClass) == false {
                        view.alpha = alpha
                    }
                }
                
                if let _UINavigationBarBackground = NSClassFromString("_UINavigationBarBackground")
                {
                    if view.isKind(of: _UINavigationBarBackground) == false {
                        view.alpha = alpha
                    }
                }
            }
        }
    }
}

/// 设置导航栏在垂直方向上平移多少距离
func wr_setTranslationY(translationY:CGFloat)
{
    transform = CGAffineTransform.init(translationX: 0, y: translationY)
}

func wr_getTranslationY() -> CGFloat
{
    return transform.ty
}

// call swizzling methods active 主动调用交换方法
private static let onceToken = UUID().uuidString
public static func wrAwake()
{
    DispatchQueue.once(token: onceToken)
    {
        let needSwizzleSelectorArr = [
            #selector(setter: titleTextAttributes)
        ]
        
        for selector in needSwizzleSelectorArr {
            let str = ("wr_" + selector.description)
            if let originalMethod = class_getInstanceMethod(self, selector),
                let swizzledMethod = class_getInstanceMethod(self, Selector(str)) {
                method_exchangeImplementations(originalMethod, swizzledMethod)
            }
        }
    }
}

//==========================================================================
// MARK: swizzling pop
//==========================================================================
@objc func wr_setTitleTextAttributes(_ newTitleTextAttributes:[String : Any]?)
{
    guard var attributes = newTitleTextAttributes else {
        return
    }
    
    guard let originTitleTextAttributes = titleTextAttributes else {
        wr_setTitleTextAttributes(attributes)
        return
    }
    
    var titleColor:UIColor?
    for attribute in originTitleTextAttributes {
        if attribute.key == NSAttributedStringKey.foregroundColor {
            titleColor = attribute.value as? UIColor
            break
        }
    }
    
    guard let originTitleColor = titleColor else {
        wr_setTitleTextAttributes(attributes)
        return
    }
    
    if attributes[NSAttributedStringKey.foregroundColor.rawValue] == nil {
        attributes.updateValue(originTitleColor, forKey: NSAttributedStringKey.foregroundColor.rawValue)
    }
    wr_setTitleTextAttributes(attributes)
}

}

//==========================================================================
// MARK: - UINavigationController
//==========================================================================
extension UINavigationController: WRFatherAwakeProtocol
{
override open var preferredStatusBarStyle: UIStatusBarStyle {
return topViewController?.wrStatusBarStyle ?? WRNavigationBar.defaultStatusBarStyle
}

fileprivate func setNeedsNavigationBarUpdate(backgroundImage: UIImage)
{
    navigationBar.wr_setBackgroundImage(image: backgroundImage)
}

fileprivate func setNeedsNavigationBarUpdate(barTintColor: UIColor)
{
    navigationBar.wr_setBackgroundColor(color: barTintColor)
}

fileprivate func setNeedsNavigationBarUpdate(barBackgroundAlpha: CGFloat)
{
    navigationBar.wr_setBackgroundAlpha(alpha: barBackgroundAlpha)
}

fileprivate func setNeedsNavigationBarUpdate(tintColor: UIColor) {
    navigationBar.tintColor = tintColor
}

fileprivate func setNeedsNavigationBarUpdate(hideShadowImage: Bool)
{
    navigationBar.shadowImage = (hideShadowImage == true) ? UIImage() : nil
}

fileprivate func setNeedsNavigationBarUpdate(titleColor: UIColor)
{
    guard let titleTextAttributes = navigationBar.titleTextAttributes else {
        navigationBar.titleTextAttributes = [NSAttributedStringKey.foregroundColor:titleColor]
        return
    }
    
    var newTitleTextAttributes = titleTextAttributes
    newTitleTextAttributes.updateValue(titleColor, forKey: NSAttributedStringKey.foregroundColor)
    navigationBar.titleTextAttributes = newTitleTextAttributes
}

fileprivate func updateNavigationBar(fromVC: UIViewController?, toVC: UIViewController?, progress: CGFloat)
{
    // change navBarBarTintColor
    let fromBarTintColor = fromVC?.navBarBarTintColor ?? WRNavigationBar.defaultNavBarBarTintColor
    let toBarTintColor   = toVC?.navBarBarTintColor ?? WRNavigationBar.defaultNavBarBarTintColor
    let newBarTintColor  = WRNavigationBar.middleColor(fromColor: fromBarTintColor, toColor: toBarTintColor, percent: progress)

// setNeedsNavigationBarUpdate(barTintColor: newBarTintColor)
// modify by sxiangyu
if WRNavigationBar.needUpdateNavigationBar(vc: fromVC) || WRNavigationBar.needUpdateNavigationBar(vc: toVC) {
setNeedsNavigationBarUpdate(barTintColor: newBarTintColor)
}

    // change navBarTintColor
    let fromTintColor = fromVC?.navBarTintColor ?? WRNavigationBar.defaultNavBarTintColor
    let toTintColor = toVC?.navBarTintColor ?? WRNavigationBar.defaultNavBarTintColor
    let newTintColor = WRNavigationBar.middleColor(fromColor: fromTintColor, toColor: toTintColor, percent: progress)

// setNeedsNavigationBarUpdate(tintColor: newTintColor)
// modify by sxiangyu
if WRNavigationBar.needUpdateNavigationBar(vc: fromVC) {
setNeedsNavigationBarUpdate(tintColor: newTintColor)
}

    // change navBarTitleColor
    //        let fromTitleColor = fromVC?.navBarTitleColor ?? WRNavigationBar.defaultNavBarTitleColor
    //        let toTitleColor = toVC?.navBarTitleColor ?? WRNavigationBar.defaultNavBarTitleColor
    //        let newTitleColor = WRNavigationBar.middleColor(fromColor: fromTitleColor, toColor: toTitleColor, percent: progress)
    //        setNeedsNavigationBarUpdate(titleColor: newTitleColor)
    
    // change navBar _UIBarBackground alpha
    let fromBarBackgroundAlpha = fromVC?.navBarBackgroundAlpha ?? WRNavigationBar.defaultBackgroundAlpha
    let toBarBackgroundAlpha = toVC?.navBarBackgroundAlpha ?? WRNavigationBar.defaultBackgroundAlpha
    let newBarBackgroundAlpha = WRNavigationBar.middleAlpha(fromAlpha: fromBarBackgroundAlpha, toAlpha: toBarBackgroundAlpha, percent: progress)
    setNeedsNavigationBarUpdate(barBackgroundAlpha: newBarBackgroundAlpha)
}

// call swizzling methods active 主动调用交换方法
private static let onceToken = UUID().uuidString
public static func fatherAwake()
{
    DispatchQueue.once(token: onceToken)
    {
        let needSwizzleSelectorArr = [
            NSSelectorFromString("_updateInteractiveTransition:"),
            #selector(popToViewController),
            #selector(popToRootViewController),
            #selector(pushViewController)
        ]
        
        for selector in needSwizzleSelectorArr {
            // _updateInteractiveTransition:  =>  wr_updateInteractiveTransition:
            let str = ("wr_" + selector.description).replacingOccurrences(of: "__", with: "_")
            if let originalMethod = class_getInstanceMethod(self, selector),
                let swizzledMethod = class_getInstanceMethod(self, Selector(str)) {
                method_exchangeImplementations(originalMethod, swizzledMethod)
            }
        }
    }
}

//==========================================================================
// MARK: swizzling pop
//==========================================================================
struct popProperties {
    fileprivate static let popDuration = 0.13
    fileprivate static var displayCount = 0
    fileprivate static var popProgress:CGFloat {
        let all:CGFloat = CGFloat(60.0 * popDuration)
        let current = min(all, CGFloat(displayCount))
        return current / all
    }
}

// swizzling system method: popToViewController
@objc func wr_popToViewController(_ viewController: UIViewController, animated: Bool) -> [UIViewController]?
{
    setNeedsNavigationBarUpdate(titleColor: viewController.navBarTitleColor)
    var displayLink:CADisplayLink? = CADisplayLink(target: self, selector: #selector(popNeedDisplay))
    // UITrackingRunLoopMode: 界面跟踪 Mode,用于 ScrollView 追踪触摸滑动,保证界面滑动时不受其他 Mode 影响
    // NSRunLoopCommonModes contains kCFRunLoopDefaultMode and UITrackingRunLoopMode
    displayLink?.add(to: RunLoop.main, forMode: .commonModes)
    CATransaction.setCompletionBlock {
        displayLink?.invalidate()
        displayLink = nil
        popProperties.displayCount = 0
    }
    CATransaction.setAnimationDuration(popProperties.popDuration)
    CATransaction.begin()
    let vcs = wr_popToViewController(viewController, animated: animated)
    CATransaction.commit()
    return vcs
}

// swizzling system method: popToRootViewControllerAnimated
@objc func wr_popToRootViewControllerAnimated(_ animated: Bool) -> [UIViewController]?
{
    var displayLink:CADisplayLink? = CADisplayLink(target: self, selector: #selector(popNeedDisplay))
    displayLink?.add(to: RunLoop.main, forMode: .commonModes)
    CATransaction.setCompletionBlock {
        displayLink?.invalidate()
        displayLink = nil
        popProperties.displayCount = 0
    }
    CATransaction.setAnimationDuration(popProperties.popDuration)
    CATransaction.begin()
    let vcs = wr_popToRootViewControllerAnimated(animated)
    CATransaction.commit()
    return vcs;
}

// change navigationBar barTintColor smooth before pop to current VC finished
@objc fileprivate func popNeedDisplay()
{
    guard let topViewController = topViewController,
        let coordinator       = topViewController.transitionCoordinator else {
            return
    }
    
    popProperties.displayCount += 1
    let popProgress = popProperties.popProgress
    // print("第\(popProperties.displayCount)次pop的进度:\(popProgress)")
    let fromVC = coordinator.viewController(forKey: .from)
    let toVC = coordinator.viewController(forKey: .to)
    updateNavigationBar(fromVC: fromVC, toVC: toVC, progress: popProgress)
}


//==========================================================================
// MARK: swizzling push
//==========================================================================
struct pushProperties {
    fileprivate static let pushDuration = 0.13
    fileprivate static var displayCount = 0
    fileprivate static var pushProgress:CGFloat {
        let all:CGFloat = CGFloat(60.0 * pushDuration)
        let current = min(all, CGFloat(displayCount))
        return current / all
    }
}

// swizzling system method: pushViewController
@objc func wr_pushViewController(_ viewController: UIViewController, animated: Bool)
{
    var displayLink:CADisplayLink? = CADisplayLink(target: self, selector: #selector(pushNeedDisplay))
    displayLink?.add(to: RunLoop.main, forMode: .commonModes)
    CATransaction.setCompletionBlock {
        displayLink?.invalidate()
        displayLink = nil
        pushProperties.displayCount = 0
        viewController.pushToCurrentVCFinished = true
    };
    CATransaction.setAnimationDuration(pushProperties.pushDuration)
    CATransaction.begin()
    wr_pushViewController(viewController, animated: animated)
    CATransaction.commit()
}

// change navigationBar barTintColor smooth before push to current VC finished or before pop to current VC finished
@objc fileprivate func pushNeedDisplay()
{
    guard let topViewController = topViewController,
        let coordinator       = topViewController.transitionCoordinator else {
            return
    }
    
    pushProperties.displayCount += 1
    let pushProgress = pushProperties.pushProgress
    // print("第\(pushProperties.displayCount)次push的进度:\(pushProgress)")
    let fromVC = coordinator.viewController(forKey: .from)
    let toVC = coordinator.viewController(forKey: .to)
    updateNavigationBar(fromVC: fromVC, toVC: toVC, progress: pushProgress)
}

}

//==========================================================================
// MARK: - deal the gesture of return
//==========================================================================
extension UINavigationController: UINavigationBarDelegate
{
public func navigationBar(_ navigationBar: UINavigationBar, shouldPop item: UINavigationItem) -> Bool
{
if let topVC = topViewController,
let coor = topVC.transitionCoordinator, coor.initiallyInteractive {
if #available(iOS 10.0, *) {
coor.notifyWhenInteractionChanges({ (context) in
self.dealInteractionChanges(context)
})
} else {
coor.notifyWhenInteractionEnds({ (context) in
self.dealInteractionChanges(context)
})
}
return true
}

    let itemCount = navigationBar.items?.count ?? 0
    let n = viewControllers.count >= itemCount ? 2 : 1
    let popToVC = viewControllers[viewControllers.count - n]
    
    popToViewController(popToVC, animated: true)
    return true
}

// deal the gesture of return break off
private func dealInteractionChanges(_ context: UIViewControllerTransitionCoordinatorContext)
{
    let animations: (UITransitionContextViewControllerKey) -> () = {
        let curColor = context.viewController(forKey: $0)?.navBarBarTintColor ?? WRNavigationBar.defaultNavBarBarTintColor
        let curAlpha = context.viewController(forKey: $0)?.navBarBackgroundAlpha ?? WRNavigationBar.defaultBackgroundAlpha
        
        self.setNeedsNavigationBarUpdate(barTintColor: curColor)
        self.setNeedsNavigationBarUpdate(barBackgroundAlpha: curAlpha)
    }
    
    // after that, cancel the gesture of return
    if context.isCancelled
    {
        let cancelDuration: TimeInterval = context.transitionDuration * Double(context.percentComplete)
        UIView.animate(withDuration: cancelDuration) {
            animations(.from)
        }
    }
    else
    {
        // after that, finish the gesture of return
        let finishDuration: TimeInterval = context.transitionDuration * Double(1 - context.percentComplete)
        UIView.animate(withDuration: finishDuration) {
            animations(.to)
        }
    }
}

// swizzling system method: _updateInteractiveTransition
@objc func wr_updateInteractiveTransition(_ percentComplete: CGFloat)
{
    guard let topViewController = topViewController,
        let coordinator       = topViewController.transitionCoordinator else {
            wr_updateInteractiveTransition(percentComplete)
            return
    }
    
    let fromVC = coordinator.viewController(forKey: .from)
    let toVC = coordinator.viewController(forKey: .to)
    updateNavigationBar(fromVC: fromVC, toVC: toVC, progress: percentComplete)
    
    wr_updateInteractiveTransition(percentComplete)
}

}

//=============================================================================
// MARK: - store navigationBar barTintColor and tintColor every viewController
//=============================================================================
extension UIViewController: WRAwakeProtocol
{
fileprivate struct AssociatedKeys
{
static var pushToCurrentVCFinished: Bool = false
static var pushToNextVCFinished:Bool = false

    static var navBarBackgroundImage: UIImage = UIImage()
    
    static var navBarBarTintColor: UIColor = WRNavigationBar.defaultNavBarBarTintColor
    static var navBarBackgroundAlpha:CGFloat = 1.0
    static var navBarTintColor: UIColor = WRNavigationBar.defaultNavBarTintColor
    static var navBarTitleColor: UIColor = WRNavigationBar.defaultNavBarTitleColor
    static var wrStatusBarStyle: UIStatusBarStyle = UIStatusBarStyle.default
    static var navBarShadowImageHidden: Bool = false
    
    static var customNavBar: UINavigationBar = UINavigationBar()
}

// navigationBar barTintColor can not change by currentVC before fromVC push to currentVC finished
fileprivate var pushToCurrentVCFinished:Bool {
    get {
        guard let isFinished = objc_getAssociatedObject(self, &AssociatedKeys.pushToCurrentVCFinished) as? Bool else {
            return false
        }
        return isFinished
    }
    set {
        objc_setAssociatedObject(self, &AssociatedKeys.pushToCurrentVCFinished, newValue, .OBJC_ASSOCIATION_ASSIGN)
    }
}

// navigationBar barTintColor can not change by currentVC when currentVC push to nextVC finished
fileprivate var pushToNextVCFinished:Bool {
    get {
        guard let isFinished = objc_getAssociatedObject(self, &AssociatedKeys.pushToNextVCFinished) as? Bool else {
            return false
        }
        return isFinished
    }
    set {
        objc_setAssociatedObject(self, &AssociatedKeys.pushToNextVCFinished, newValue, .OBJC_ASSOCIATION_ASSIGN)
    }
}

// you can set navigationBar backgroundImage
var navBarBackgroundImage: UIImage?
{
    get {
        guard let bgImage = objc_getAssociatedObject(self, &AssociatedKeys.navBarBackgroundImage) as? UIImage else {
            return WRNavigationBar.defaultNavBarBackgroundImage
        }
        return bgImage
    }
    //        set {
    //            if customNavBar.isKind(of: UINavigationBar.self) {
    //                let navBar = customNavBar as! UINavigationBar
    //                navBar.wr_setBackgroundImage(image: newValue!)
    //            }
    //            else {
    //                objc_setAssociatedObject(self, &AssociatedKeys.navBarBackgroundImage, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
    //            }
    //        }
}

// navigationBar barTintColor
var navBarBarTintColor: UIColor {
    get {
        
        /// add by sxiangyu
        guard WRNavigationBar.needUpdateNavigationBar(vc: self) else {
            return self.navigationController?.navigationBar.barTintColor ?? WRNavigationBar.defaultNavBarBarTintColor
        }
        
        guard let barTintColor = objc_getAssociatedObject(self, &AssociatedKeys.navBarBarTintColor) as? UIColor else {
            return WRNavigationBar.defaultNavBarBarTintColor
        }
        return barTintColor
    }
    set {
        objc_setAssociatedObject(self, &AssociatedKeys.navBarBarTintColor, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
        
        if customNavBar.isKind(of: UINavigationBar.self) {
            //                let navBar = customNavBar as! UINavigationBar
            //                navBar.wr_setBackgroundColor(color: newValue)
        }
        else {
            if canUpdateNavBarBarTintColorOrBackgroundAlpha == true {
                navigationController?.setNeedsNavigationBarUpdate(barTintColor: newValue)
            }
        }
    }
}

// navigationBar _UIBarBackground alpha
var navBarBackgroundAlpha:CGFloat {
    get {
        guard let barBackgroundAlpha = objc_getAssociatedObject(self, &AssociatedKeys.navBarBackgroundAlpha) as? CGFloat else {
            return 1.0
        }
        return barBackgroundAlpha
    }
    set {
        objc_setAssociatedObject(self, &AssociatedKeys.navBarBackgroundAlpha, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
        
        if customNavBar.isKind(of: UINavigationBar.self) {
            //                let navBar = customNavBar as! UINavigationBar
            //                navBar.wr_setBackgroundAlpha(alpha: newValue)
        }
        else {
            if canUpdateNavBarBarTintColorOrBackgroundAlpha == true {
                navigationController?.setNeedsNavigationBarUpdate(barBackgroundAlpha: newValue)
            }
        }
    }
}
private var canUpdateNavBarBarTintColorOrBackgroundAlpha:Bool {
    get {
        let isRootViewController = self.navigationController?.viewControllers.first == self
        if (pushToCurrentVCFinished == true || isRootViewController == true) && pushToNextVCFinished == false {
            return true
        } else {
            return false
        }
    }
}

// navigationBar tintColor
var navBarTintColor: UIColor {
    get {
        
        /// add by sxiangyu
        guard WRNavigationBar.needUpdateNavigationBar(vc: self) else {
            return self.navigationController?.navigationBar.tintColor ?? WRNavigationBar.defaultNavBarTintColor
        }
        
        guard let tintColor = objc_getAssociatedObject(self, &AssociatedKeys.navBarTintColor) as? UIColor else {
            return WRNavigationBar.defaultNavBarTintColor
        }
        return tintColor
    }
    set {
        objc_setAssociatedObject(self, &AssociatedKeys.navBarTintColor, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
        
        if customNavBar.isKind(of: UINavigationBar.self) {
            //                let navBar = customNavBar as! UINavigationBar
            //                navBar.tintColor = newValue
        }
        else
        {
            if pushToNextVCFinished == false {
                navigationController?.setNeedsNavigationBarUpdate(tintColor: newValue)
            }
        }
    }
}

// navigationBar titleColor
var navBarTitleColor: UIColor {
    get {
        
        /// add by sxiangyu
        guard WRNavigationBar.needUpdateNavigationBar(vc: self) else {
            return (self.navigationController?.navigationBar.titleTextAttributes?[NSAttributedStringKey.foregroundColor] as? UIColor) ?? WRNavigationBar.defaultNavBarTitleColor
        }
        
        guard let titleColor = objc_getAssociatedObject(self, &AssociatedKeys.navBarTitleColor) as? UIColor else {
            return WRNavigationBar.defaultNavBarTitleColor
        }
        return titleColor
    }
    set {
        objc_setAssociatedObject(self, &AssociatedKeys.navBarTitleColor, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
        
        if customNavBar.isKind(of: UINavigationBar.self) {
            //                let navBar = customNavBar as! UINavigationBar
            //                navBar.titleTextAttributes = [NSAttributedStringKey.foregroundColor:newValue]
        }
        else
        {
            if pushToNextVCFinished == false {
                navigationController?.setNeedsNavigationBarUpdate(titleColor: newValue)
            }
        }
    }
}

// statusBarStyle
var wrStatusBarStyle: UIStatusBarStyle {
    get {
        guard let style = objc_getAssociatedObject(self, &AssociatedKeys.wrStatusBarStyle) as? UIStatusBarStyle else {
            return WRNavigationBar.defaultStatusBarStyle
        }
        return style
    }
    set {
        objc_setAssociatedObject(self, &AssociatedKeys.wrStatusBarStyle, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
        setNeedsStatusBarAppearanceUpdate()
    }
}

// if you want shadowImage hidden,you can via hideShadowImage = true
var navBarShadowImageHidden:Bool {
    get {
        guard let isHidden = objc_getAssociatedObject(self, &AssociatedKeys.navBarShadowImageHidden) as? Bool else {
            return WRNavigationBar.defaultShadowImageHidden
        }
        return isHidden
    }
    set {
        objc_setAssociatedObject(self, &AssociatedKeys.navBarShadowImageHidden, newValue, .OBJC_ASSOCIATION_ASSIGN)
        navigationController?.setNeedsNavigationBarUpdate(hideShadowImage: newValue)
    }
}

// custom navigationBar
var customNavBar: UIView {
    get {
        guard let navBar = objc_getAssociatedObject(self, &AssociatedKeys.customNavBar) as? UINavigationBar else {
            return UIView()
        }
        return navBar
    }
    set {
        objc_setAssociatedObject(self, &AssociatedKeys.customNavBar, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
    }
}

// swizzling two system methods: viewWillAppear(_:) and viewWillDisappear(_:)
private static let onceToken = UUID().uuidString
@objc public static func wrAwake()
{
    DispatchQueue.once(token: onceToken)
    {
        let needSwizzleSelectors = [
            #selector(viewWillAppear(_:)),
            #selector(viewWillDisappear(_:)),
            #selector(viewDidAppear(_:))
        ]
        
        for selector in needSwizzleSelectors
        {
            let newSelectorStr = "wr_" + selector.description
            if let originalMethod = class_getInstanceMethod(self, selector),
                let swizzledMethod = class_getInstanceMethod(self, Selector(newSelectorStr)) {
                method_exchangeImplementations(originalMethod, swizzledMethod)
            }
        }
    }
}

@objc func wr_viewWillAppear(_ animated: Bool)
{
    if canUpdateNavigationBar() == true {
        pushToNextVCFinished = false
        navigationController?.setNeedsNavigationBarUpdate(tintColor: navBarTintColor)
        navigationController?.setNeedsNavigationBarUpdate(titleColor: navBarTitleColor)
    }
    wr_viewWillAppear(animated)
}

@objc func wr_viewWillDisappear(_ animated: Bool)
{
    if canUpdateNavigationBar() == true {
        pushToNextVCFinished = true
    }
    wr_viewWillDisappear(animated)
}

@objc func wr_viewDidAppear(_ animated: Bool)
{
    
    if self.navigationController?.viewControllers.first != self {
        self.pushToCurrentVCFinished = true
    }
    if canUpdateNavigationBar() == true
    {
        if let navBarBgImage = navBarBackgroundImage {
            navigationController?.setNeedsNavigationBarUpdate(backgroundImage: navBarBgImage)
        } else {
            navigationController?.setNeedsNavigationBarUpdate(barTintColor: navBarBarTintColor)
        }
        navigationController?.setNeedsNavigationBarUpdate(barBackgroundAlpha: navBarBackgroundAlpha)
        navigationController?.setNeedsNavigationBarUpdate(tintColor: navBarTintColor)
        navigationController?.setNeedsNavigationBarUpdate(titleColor: navBarTitleColor)
        navigationController?.setNeedsNavigationBarUpdate(hideShadowImage: navBarShadowImageHidden)
    }
    wr_viewDidAppear(animated)
}

func canUpdateNavigationBar() -> Bool
{
    /// add by sxiangyu
    guard WRNavigationBar.needUpdateNavigationBar(vc: self) else {
        return false
    }
    
    let viewFrame = view.frame
    let maxFrame = UIScreen.main.bounds
    let middleFrame = CGRect(x: 0, y: WRNavigationBar.navBarBottom(), width: WRNavigationBar.screenWidth(), height: WRNavigationBar.screenHeight()-WRNavigationBar.navBarBottom())
    let minFrame = CGRect(x: 0, y: WRNavigationBar.navBarBottom(), width: WRNavigationBar.screenWidth(), height: WRNavigationBar.screenHeight()-WRNavigationBar.navBarBottom()-WRNavigationBar.tabBarHeight())
    // 蝙蝠🦇
    let isBat = viewFrame.equalTo(maxFrame) || viewFrame.equalTo(middleFrame) || viewFrame.equalTo(minFrame)
    if self.navigationController != nil && isBat == true {
        return true
    } else {
        return false
    }
}

}

//====================================================================================
// MARK: - Swizzling会改变全局状态,所以用 DispatchQueue.once 来确保无论多少线程都只会被执行一次
//====================================================================================
extension DispatchQueue {

private static var onceTracker = [String]()

//Executes a block of code, associated with a unique token, only once.  The code is thread safe and will only execute the code once even in the presence of multithreaded calls.
public class func once(token: String, block: () -> Void)
{   // 保证被 objc_sync_enter 和 objc_sync_exit 包裹的代码可以有序同步地执行
    objc_sync_enter(self)
    defer { // 作用域结束后执行defer中的代码
        objc_sync_exit(self)
    }
    
    if onceTracker.contains(token) {
        return
    }
    
    onceTracker.append(token)
    block()
}

}

//===========================================================================================
// MARK: - default navigationBar barTintColor、tintColor and statusBarStyle YOU CAN CHANGE!!!
//===========================================================================================
class WRNavigationBar
{
fileprivate struct AssociatedKeys
{ // default is system attributes
static var defNavBarBarTintColor: UIColor = UIColor.white
static var defNavBarBackgroundImage: UIImage = UIImage()
static var defNavBarTintColor: UIColor = UIColor(red: 0, green: 0.478431, blue: 1, alpha: 1.0)
static var defNavBarTitleColor: UIColor = UIColor.black
static var defStatusBarStyle: UIStatusBarStyle = UIStatusBarStyle.default
static var defShadowImageHidden: Bool = false
}

class var defaultNavBarBarTintColor: UIColor {
    get {
        guard let def = objc_getAssociatedObject(self, &AssociatedKeys.defNavBarBarTintColor) as? UIColor else {
            return AssociatedKeys.defNavBarBarTintColor
        }
        return def
    }
    set {
        objc_setAssociatedObject(self, &AssociatedKeys.defNavBarBarTintColor, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
    }
}

class var defaultNavBarBackgroundImage: UIImage? {
    get {
        guard let def = objc_getAssociatedObject(self, &AssociatedKeys.defNavBarBackgroundImage) as? UIImage else {
            return nil
        }
        return def
    }
    set {
        objc_setAssociatedObject(self, &AssociatedKeys.defNavBarBackgroundImage, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
    }
}

class var defaultNavBarTintColor: UIColor {
    get {
        guard let def = objc_getAssociatedObject(self, &AssociatedKeys.defNavBarTintColor) as? UIColor else {
            return AssociatedKeys.defNavBarTintColor
        }
        return def
    }
    set {
        objc_setAssociatedObject(self, &AssociatedKeys.defNavBarTintColor, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
    }
}

class var defaultNavBarTitleColor: UIColor {
    get {
        guard let def = objc_getAssociatedObject(self, &AssociatedKeys.defNavBarTitleColor) as? UIColor else {
            return AssociatedKeys.defNavBarTitleColor
        }
        return def
    }
    set {
        objc_setAssociatedObject(self, &AssociatedKeys.defNavBarTitleColor, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
    }
}

class var defaultStatusBarStyle: UIStatusBarStyle {
    get {
        guard let def = objc_getAssociatedObject(self, &AssociatedKeys.defStatusBarStyle) as? UIStatusBarStyle else {
            return .default
        }
        return def
    }
    set {
        objc_setAssociatedObject(self, &AssociatedKeys.defStatusBarStyle, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
    }
}

class var defaultShadowImageHidden: Bool {
    get {
        guard let def = objc_getAssociatedObject(self, &AssociatedKeys.defShadowImageHidden) as? Bool else {
            return false
        }
        return def
    }
    set {
        objc_setAssociatedObject(self, &AssociatedKeys.defShadowImageHidden, newValue, .OBJC_ASSOCIATION_ASSIGN)
    }
}

class var defaultBackgroundAlpha: CGFloat {
    get {
        return 1.0
    }
}

// Calculate the middle Color with translation percent
class fileprivate func middleColor(fromColor: UIColor, toColor: UIColor, percent: CGFloat) -> UIColor
{
    // get current color RGBA
    var fromRed: CGFloat = 0
    var fromGreen: CGFloat = 0
    var fromBlue: CGFloat = 0
    var fromAlpha: CGFloat = 0
    fromColor.getRed(&fromRed, green: &fromGreen, blue: &fromBlue, alpha: &fromAlpha)
    
    // get to color RGBA
    var toRed: CGFloat = 0
    var toGreen: CGFloat = 0
    var toBlue: CGFloat = 0
    var toAlpha: CGFloat = 0
    toColor.getRed(&toRed, green: &toGreen, blue: &toBlue, alpha: &toAlpha)
    
    // calculate middle color RGBA
    let newRed = fromRed + (toRed - fromRed) * percent
    let newGreen = fromGreen + (toGreen - fromGreen) * percent
    let newBlue = fromBlue + (toBlue - fromBlue) * percent
    let newAlpha = fromAlpha + (toAlpha - fromAlpha) * percent
    return UIColor(red: newRed, green: newGreen, blue: newBlue, alpha: newAlpha)
}

// Calculate the middle alpha
class fileprivate func middleAlpha(fromAlpha: CGFloat, toAlpha: CGFloat, percent: CGFloat) -> CGFloat
{
    let newAlpha = fromAlpha + (toAlpha - fromAlpha) * percent
    return newAlpha
}

/// add by sxiangyu 是否需要更新
class fileprivate func needUpdateNavigationBar(vc: UIViewController?) -> Bool {
    
    if let _ = vc as? INNOBaseViewController {
        return true
    } else {
        return false
    }
    
}

}

extension WRNavigationBar
{
class func isIphoneX() -> Bool {
return UIScreen.main.bounds.equalTo(CGRect(x: 0, y: 0, width: 375, height: 812)) ||
UIScreen.main.bounds.equalTo(CGRect(x: 0, y: 0, width: 812, height: 375)) ||
UIScreen.main.bounds.equalTo(CGRect(x: 0, y: 0, width: 414, height: 896)) ||
UIScreen.main.bounds.equalTo(CGRect(x: 0, y: 0, width: 896, height: 414))
}
class func navBarBottom() -> Int {
return self.isIphoneX() ? 88 : 64;
}
class func tabBarHeight() -> Int {
return self.isIphoneX() ? 83 : 49;
}
class func screenWidth() -> Int {
return Int(UIScreen.main.bounds.size.width)
}
class func screenHeight() -> Int {
return Int(UIScreen.main.bounds.size.height)
}
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// 1. 定义 WRAwakeProtocol 协议
public protocol WRAwakeProtocol: class {
static func wrAwake()
}
public protocol WRFatherAwakeProtocol: class
{ // 1.1 定义 WRFatherAwakeProtocol ()
static func fatherAwake()
}

class NothingToSeeHere
{
static func harmlessFunction(){
// let typeCount = Int(objc_getClassList(nil, 0))
// let types = UnsafeMutablePointer<AnyClass?>.allocate(capacity: typeCount)
// let autoreleaseintTypes = AutoreleasingUnsafeMutablePointer(types)
// objc_getClassList(autoreleaseintTypes, Int32(typeCount)) //获取所有的类
// for index in 0 ..< typeCount {
// (types[index] as? WRAwakeProtocol.Type)?.wrAwake() //如果该类实现了SelfAware协议,那么调用 awake 方法
// (types[index] as? WRFatherAwakeProtocol.Type)?.fatherAwake()
// }
// types.deallocate(capacity: typeCount)

    // !!!这边不能按照注释的写循环,否则启动会卡住线程(15000多个循环)
    
    // 实现了SelfAware协议,那么调用 awake 方法
    UINavigationBar.wrAwake()
    UIViewController.wrAwake()
    UINavigationController.fatherAwake()
}

}

// 2. 让APP启动时只执行一次 harmlessFunction 方法
extension UIApplication
{
private static let runOnce:Void = { //使用静态属性以保证只调用一次(该属性是个方法)
NothingToSeeHere.harmlessFunction()
}()

open override var next: UIResponder?{ //重写next属性
    UIApplication.runOnce
    return super.next
}

}

// 3. 自定义类实现 WRAwakeProtocol 协议,重写 wrAwake 方法
// 自定义类实现 WRFatherAwakeProtocol 协议,重写 fatherAwake 方法
`

主要修改
`class fileprivate func needUpdateNavigationBar(vc: UIViewController?) -> Bool {

    if let _ = vc as? INNOBaseViewController {
        return true
    } else {
        return false
    }
    
}`

这里面的方法,我这边是有个公共的baseVC ,所以这样判断,大家可以可以设置黑名单列表之类的,在这里面判断。主要模仿OC的方式。

xocde9 ios11 崩溃

设置 self.navBarBackgroundAlpha = 1; 后,没有效果

反而这段代码崩溃
fileprivate func wr_setBackgroundAlpha(alpha:CGFloat)
{
let barBackgroundView = subviews[0] // 这会崩溃
barBackgroundView.alpha = alpha
}

设置无效

导航栏设置的时候不会发生变化,没有走get方法

crash on some device iOS 14 for ipad

crash on

(types[index] as? WRAwakeProtocol.Type)?.wrAwake()
(types[index] as? WRFatherAwakeProtocol.Type)?.fatherAwake()

solution:

// (types[index] as? WRAwakeProtocol.Type)?.wrAwake()
// (types[index] as? WRFatherAwakeProtocol.Type)?.fatherAwake()

不支持storyboard

在storyboard中创建的导航控制器,在其根试图控制器中滑动改变导航栏透明度无效,导航栏始终是透明的

在 xcode 9 上

// 自定义导航栏必须设置这个属性!!!!!!
customNavBar = navBar
view.addSubview(navBar)
// 设置导航栏颜色
navBarBarTintColor = BaseColor
// 设置初始导航栏透明度
navBarBackgroundAlpha = 0
// 设置导航栏按钮
navBarTintColor = .white
// 设置标题文字颜色
navBarTitleColor = .white
navBarShadowImageHidden = true

这段代码 会不显示

IOS11.1 上传appstore后下载打开app就崩溃

RT 附上日志
6 XXX 0x10429460c specialized UINavigationBar.wr_setTitleTextAttributes(:) + 1639948 (WRNavigationBar.swift:0)
7 XXX 0x10428f210 @objc UINavigationBar.wr_setTitleTextAttributes(
:) + 1618448 (WRNavigationBar.swift:0)
8 XXX 0x1042949f8 specialized UINavigationController.setNeedsNavigationBarUpdate(titleColor:) + 1640952 (WRNavigationBar.swift:246)
9 XXX 0x104291540 UIViewController.wr_viewWillAppear(:) + 1627456 (WRNavigationBar.swift:730)
10 XXX 0x104291a80 @objc UIViewController.wr_viewWillAppear(
:) + 1628800 (WRNavigationBar.swift:0)
11 XXX 0x1041fbb18 BaseViewController.viewWillAppear(:) + 1014552 (BaseViewController.swift:119)
12 XXX 0x1041fbee8 @objc BaseViewController.viewWillAppear(
:) + 1015528 (BaseViewController.swift:0)

crash on some device iOS 14 for ipad

crash on

(types[index] as? WRAwakeProtocol.Type)?.wrAwake()
(types[index] as? WRFatherAwakeProtocol.Type)?.fatherAwake()

solution:

```

// (types[index] as? WRAwakeProtocol.Type)?.wrAwake()
// (types[index] as? WRFatherAwakeProtocol.Type)?.fatherAwake()


Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.