Skip to content

Commit

Permalink
format code
Browse files Browse the repository at this point in the history
  • Loading branch information
huangboju committed Mar 16, 2017
1 parent 6899dfa commit 0e98209
Showing 1 changed file with 115 additions and 124 deletions.
239 changes: 115 additions & 124 deletions ETNavBarTransparent/ETNavBarTransparent.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,26 @@ import UIKit

extension UIColor {
//System default bar tint color
open class func defaultNavBarTintColor() -> UIColor {
open class var defaultNavBarTintColor: UIColor {
return UIColor(red: 0, green: 0.478431, blue: 1, alpha: 1.0)
}
}

extension DispatchQueue {

private static var _onceTracker = [String]()

public class func once(token: String, block: () -> Void) {
objc_sync_enter(self)
defer { objc_sync_exit(self) }

if _onceTracker.contains(token) {
return
}

_onceTracker.append(token)
block()
}
}

extension UINavigationController {
Expand All @@ -27,53 +43,55 @@ extension UINavigationController {
return topViewController?.preferredStatusBarStyle ?? .default
}

static let _onceToken = UUID().uuidString

open override class func initialize(){

if self == UINavigationController.self {

let needSwizzleSelectorArr = [["ori":NSSelectorFromString("_updateInteractiveTransition:"),"swi":NSSelectorFromString("et_updateInteractiveTransition:")],
["ori":#selector(popToViewController(_:animated:)),"swi":#selector(et_popToViewController(_:animated:))],
["ori":#selector(popToRootViewController(animated:)),"swi":#selector(et_popToRootViewController(animated:))]]

for needSwizzleSelector in needSwizzleSelectorArr {
let originalSelector = needSwizzleSelector["ori"]
let swizzledSelector = needSwizzleSelector["swi"]
let originalMethod = class_getInstanceMethod(self.classForCoder(), originalSelector)
let swizzledMethod = class_getInstanceMethod(self.classForCoder(), swizzledSelector)
method_exchangeImplementations(originalMethod, swizzledMethod)
DispatchQueue.once(token: _onceToken) {
let needSwizzleSelectorArr = [
NSSelectorFromString("_updateInteractiveTransition:"),
#selector(popToViewController),
#selector(popToRootViewController)
]

for selector in needSwizzleSelectorArr {

let str = ("et_" + selector.description).replacingOccurrences(of: "__", with: "_")
let originalMethod = class_getInstanceMethod(self, selector)
let swizzledMethod = class_getInstanceMethod(self, Selector(str))
method_exchangeImplementations(originalMethod, swizzledMethod)
}
}

}

}


func et_updateInteractiveTransition(_ percentComplete: CGFloat) {
et_updateInteractiveTransition(percentComplete)
if let topVC = self.topViewController {
if let coor = topVC.transitionCoordinator {
//Bg Alpha
let fromAlpha = coor.viewController(forKey: .from)?.navBarBgAlpha
let toAlpha = coor.viewController(forKey: .to)?.navBarBgAlpha
let nowAlpha = fromAlpha! + (toAlpha!-fromAlpha!)*percentComplete

self.setNeedsNavigationBackground(alpha: nowAlpha)

//tintColor
let fromColor = coor.viewController(forKey: .from)?.navBarTintColor
let toColor = coor.viewController(forKey: .to)?.navBarTintColor
let nowColor = averageColor(fromColor: fromColor!, toColor: toColor!, percent: percentComplete)
self.navigationBar.tintColor = nowColor
}
}
guard let topVC = topViewController, let coor = topVC.transitionCoordinator else { return }

//Bg Alpha
let fromAlpha = coor.viewController(forKey: .from)?.navBarBgAlpha ?? 0
let toAlpha = coor.viewController(forKey: .to)?.navBarBgAlpha ?? 0
let nowAlpha = fromAlpha + (toAlpha - fromAlpha) * percentComplete

setNeedsNavigationBackground(alpha: nowAlpha)

//tintColor
let fromColor = coor.viewController(forKey: .from)?.navBarTintColor ?? .blue
let toColor = coor.viewController(forKey: .to)?.navBarTintColor ?? .blue
let nowColor = averageColor(fromColor: fromColor, toColor: toColor, percent: percentComplete)
navigationBar.tintColor = nowColor
}

//Calculate the middle Color with translation percent
private func averageColor(fromColor:UIColor, toColor:UIColor, percent:CGFloat) -> UIColor {
var fromRed :CGFloat = 0.0
var fromGreen :CGFloat = 0.0
var fromBlue :CGFloat = 0.0
var fromAlpha :CGFloat = 0.0
var fromRed: CGFloat = 0.0
var fromGreen: CGFloat = 0.0
var fromBlue: CGFloat = 0.0
var fromAlpha: CGFloat = 0.0
fromColor.getRed(&fromRed, green: &fromGreen, blue: &fromBlue, alpha: &fromAlpha)

var toRed :CGFloat = 0.0
Expand All @@ -82,30 +100,27 @@ extension UINavigationController {
var toAlpha :CGFloat = 0.0
toColor.getRed(&toRed, green: &toGreen, blue: &toBlue, alpha: &toAlpha)

let nowRed = fromRed + (toRed-fromRed)*percent
let nowGreen = fromGreen + (toGreen-fromGreen)*percent
let nowBlue = fromBlue + (toBlue-fromBlue)*percent
let nowAlpha = fromAlpha + (toAlpha-fromAlpha)*percent
let nowRed = fromRed + (toRed - fromRed) * percent
let nowGreen = fromGreen + (toGreen - fromGreen) * percent
let nowBlue = fromBlue + (toBlue - fromBlue) * percent
let nowAlpha = fromAlpha + (toAlpha - fromAlpha) * percent

return UIColor(red: nowRed, green: nowGreen, blue: nowBlue, alpha: nowAlpha)
}


func et_popToViewController(_ viewController: UIViewController, animated: Bool) -> [UIViewController]? {
setNeedsNavigationBackground(alpha: (viewController.navBarBgAlpha))
setNeedsNavigationBackground(alpha: viewController.navBarBgAlpha)
navigationBar.tintColor = viewController.navBarTintColor
return et_popToViewController(viewController, animated: animated)
}

func et_popToRootViewController(animated: Bool) -> [UIViewController]? {
setNeedsNavigationBackground(alpha: (viewControllers.first?.navBarBgAlpha)!)
setNeedsNavigationBackground(alpha: viewControllers.first?.navBarBgAlpha ?? 0)
navigationBar.tintColor = viewControllers.first?.navBarTintColor
return et_popToRootViewController(animated: animated)
}


fileprivate func setNeedsNavigationBackground(alpha:CGFloat) {


let barBackgroundView = navigationBar.subviews[0]
if let shadowView = barBackgroundView.value(forKey: "_shadowView") as? UIView {
Expand All @@ -114,125 +129,105 @@ extension UINavigationController {

if navigationBar.isTranslucent {
if #available(iOS 10.0, *){
if navigationBar.backgroundImage(for: .default) == nil {
if let backgroundEffectView = barBackgroundView.value(forKey: "_backgroundEffectView") as? UIView {
backgroundEffectView.alpha = alpha
return
}
guard navigationBar.backgroundImage(for: .default) == nil else {
return
}


if let backgroundEffectView = barBackgroundView.value(forKey: "_backgroundEffectView") as? UIView {
backgroundEffectView.alpha = alpha
return
}

}else{
if let adaptiveBackdrop = barBackgroundView.value(forKey: "_adaptiveBackdrop") as? UIView {
if let backdropEffectView = adaptiveBackdrop.value(forKey: "_backdropEffectView") as? UIView {
backdropEffectView.alpha = alpha
return
}
guard let adaptiveBackdrop = barBackgroundView.value(forKey: "_adaptiveBackdrop") as? UIView else {
return
}

if let backdropEffectView = adaptiveBackdrop.value(forKey: "_backdropEffectView") as? UIView {
backdropEffectView.alpha = alpha
return
}
}


}

barBackgroundView.alpha = alpha

}


}

extension UINavigationController:UINavigationControllerDelegate,UINavigationBarDelegate {

extension UINavigationController: UINavigationControllerDelegate,UINavigationBarDelegate {
public func navigationController(_ navigationController: UINavigationController, willShow viewController: UIViewController, animated: Bool) {
if let topVC = navigationController.topViewController {
if let coor = topVC.transitionCoordinator {
if #available(iOS 10.0, *) {
coor.notifyWhenInteractionChanges({ (context) in
self.dealInteractionChanges(context)
})
} else {
coor.notifyWhenInteractionEnds({ (context) in
self.dealInteractionChanges(context)
})

}
}
guard let topVC = navigationController.topViewController, let coor = topVC.transitionCoordinator else {
return
}

if #available(iOS 10.0, *) {
coor.notifyWhenInteractionChanges({ (context) in
self.dealInteractionChanges(context)
})
} else {
coor.notifyWhenInteractionEnds({ (context) in
self.dealInteractionChanges(context)
})
}
}

private func dealInteractionChanges(_ context:UIViewControllerTransitionCoordinatorContext) {
private func dealInteractionChanges(_ context: UIViewControllerTransitionCoordinatorContext) {
let animations: (UITransitionContextViewControllerKey) -> () = {
let nowAlpha = context.viewController(forKey: $0)?.navBarBgAlpha ?? 0
self.setNeedsNavigationBackground(alpha: nowAlpha)

self.navigationBar.tintColor = context.viewController(forKey: $0)?.navBarTintColor
}

if context.isCancelled {
let cancellDuration:TimeInterval = context.transitionDuration * Double( context.percentComplete)
let cancellDuration: TimeInterval = context.transitionDuration * Double(context.percentComplete)
UIView.animate(withDuration: cancellDuration, animations: {

let nowAlpha = (context.viewController(forKey: .from)?.navBarBgAlpha)!
self.setNeedsNavigationBackground(alpha: nowAlpha)

self.navigationBar.tintColor = context.viewController(forKey: .from)?.navBarTintColor
animations(.from)
})
}else{
let finishDuration:TimeInterval = context.transitionDuration * Double(1 - context.percentComplete)
} else {
let finishDuration: TimeInterval = context.transitionDuration * Double(1 - context.percentComplete)
UIView.animate(withDuration: finishDuration, animations: {
let nowAlpha = (context.viewController(forKey: .to)?.navBarBgAlpha)!
self.setNeedsNavigationBackground(alpha: nowAlpha)

self.navigationBar.tintColor = context.viewController(forKey: .to)?.navBarTintColor
animations(.to)
})
}
}



public func navigationBar(_ navigationBar: UINavigationBar, shouldPop item: UINavigationItem) -> Bool {
if let topVC = topViewController {
if let coor = topVC.transitionCoordinator {
if coor.initiallyInteractive {
return true
}
}
if let topVC = topViewController, let coor = topVC.transitionCoordinator, coor.initiallyInteractive {
return true
}

let itemCount = navigationBar.items?.count ?? 0
let n = viewControllers.count >= itemCount ? 2 : 1
let popToVC = viewControllers[viewControllers.count - n]

var popToVC: UIViewController?
if viewControllers.count >= (navigationBar.items?.count)! {
popToVC = viewControllers[viewControllers.count-2]
}else{
popToVC = viewControllers[viewControllers.count-1]
}
popToViewController(popToVC, animated: true)

if popToVC != nil {
_ = self.popToViewController(popToVC!, animated: true)
return true
}

return false
return true
}

public func navigationBar(_ navigationBar: UINavigationBar, shouldPush item: UINavigationItem) -> Bool {
setNeedsNavigationBackground(alpha: (topViewController?.navBarBgAlpha)!)
setNeedsNavigationBackground(alpha: topViewController?.navBarBgAlpha ?? 0)
navigationBar.tintColor = topViewController?.navBarTintColor
return true
}

}




extension UIViewController {

fileprivate struct AssociatedKeys {
static var navBarBgAlpha: CGFloat = 1.0
static var navBarTintColor: UIColor = UIColor.defaultNavBarTintColor()
static var navBarTintColor: UIColor = UIColor.defaultNavBarTintColor
}

open var navBarBgAlpha: CGFloat {
get {
let alpha = objc_getAssociatedObject(self, &AssociatedKeys.navBarBgAlpha) as? CGFloat
if alpha == nil {

guard let alpha = objc_getAssociatedObject(self, &AssociatedKeys.navBarBgAlpha) as? CGFloat else {
return 1.0
}else{
return alpha!
}
return alpha

}
set {
Expand All @@ -253,19 +248,15 @@ extension UIViewController {

open var navBarTintColor: UIColor {
get {
let tintColor = objc_getAssociatedObject(self, &AssociatedKeys.navBarTintColor) as? UIColor
if tintColor == nil {
return UIColor.defaultNavBarTintColor()
}else{
return tintColor!
guard let tintColor = objc_getAssociatedObject(self, &AssociatedKeys.navBarTintColor) as? UIColor else {
return UIColor.defaultNavBarTintColor
}
return tintColor

}
set {
navigationController?.navigationBar.tintColor = newValue
objc_setAssociatedObject(self, &AssociatedKeys.navBarTintColor, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
}
}


}

0 comments on commit 0e98209

Please sign in to comment.