ZoneNavigationBarManager.swift 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297
  1. //
  2. // ZoneNavigationBarManager.swift
  3. // ZoneBarManager
  4. //
  5. // Created by 刘振兴 on 2017/3/10.
  6. // Copyright © 2017年 zone. All rights reserved.
  7. //
  8. import UIKit
  9. class ZoneNavigationBarManager: NSObject {
  10. //NavigationBar background color, default is white
  11. open var barColor:UIColor!
  12. //NavigationBar subviews color
  13. open var tintColor:UIColor!
  14. //default is nil
  15. open var backgroundImage:UIImage!
  16. // default is UIStatusBarStyleDefault
  17. open var statusBarStyle:UIStatusBarStyle!
  18. //color will changed begin this offset, default is -64
  19. open var zeroAlphaOffset:Float = 0.0
  20. //color alpha will be 1 in this offset, default is 200
  21. open var fullAlphaOffset:Float = 0.0
  22. //bar minAlpha, default is 0
  23. open var minAlphaValue:Float = 0.0
  24. //bar maxAlpha, default is 1
  25. open var maxAlphaValue:Float = 1.0
  26. //if you set this property, the tintColor will changed in fullAlphaOffset
  27. open var fullAlphaTintColor:UIColor!
  28. //if you set this property, the barStyle will changed in fullAlphaOffset
  29. open var fullAlphaBarStyle:UIStatusBarStyle!
  30. //if allchange = yes, the tintColor will changed with the barColor change, default is yes, if you only want to change barColor, set allChange = NO
  31. open var allChange:Bool = true
  32. //this will cause that if currentAlpha = 0.3,it will be 1 - 0.3 = 0.7
  33. open var reversal:Bool = true
  34. //when continues = YES, bar color will changed whenever you scroll, if you set continues = NO,it only be changed in the fullAlphaOffset
  35. open var continues:Bool = true
  36. //private const
  37. private static let kNavigationBarHeight:Float = 64.0
  38. private static let kDefaultFullOffset:Float = 200.0
  39. private static let kMaxAlphaValue:Float = 0.995
  40. private static let kMinAlphaValue:Float = 0.0
  41. private static let kDefaultAnimationTime:Float = 0.35
  42. //store source
  43. private var selfNavigationBar:UINavigationBar!
  44. private var selfNavigationController:UINavigationController!
  45. private var saveIsTranslucent:Bool = true
  46. private var saveImage:UIImage!
  47. private var saveColor:UIColor!
  48. private var saveTintColor:UIColor!
  49. private var saveTitleAttributes:[NSAttributedString.Key:Any]!
  50. private var saveBarStyle:UIStatusBarStyle!
  51. private var setFull:Bool = true
  52. private var setZero:Bool = true
  53. private var setChange:Bool = true
  54. //单例
  55. private class var sharedManager:ZoneNavigationBarManager {
  56. struct SingletonWrapper {
  57. static let singleton = ZoneNavigationBarManager()
  58. }
  59. return SingletonWrapper.singleton
  60. }
  61. private override init(){
  62. super.init()
  63. self.maxAlphaValue = ZoneNavigationBarManager.kMaxAlphaValue
  64. self.minAlphaValue = ZoneNavigationBarManager.kMinAlphaValue
  65. self.fullAlphaOffset = Float(ZoneNavigationBarManager.kDefaultFullOffset)
  66. self.zeroAlphaOffset = -(Float)(ZoneNavigationBarManager.kNavigationBarHeight)
  67. self.setZero = true
  68. self.setFull = true
  69. self.allChange = true
  70. self.continues = true
  71. //self.initBaseData(self)
  72. }
  73. private func initBaseData(_ manager:ZoneNavigationBarManager){
  74. manager.maxAlphaValue = ZoneNavigationBarManager.kMaxAlphaValue
  75. manager.minAlphaValue = ZoneNavigationBarManager.kMinAlphaValue
  76. manager.fullAlphaOffset = Float(ZoneNavigationBarManager.kDefaultFullOffset)
  77. manager.zeroAlphaOffset = -(Float)(ZoneNavigationBarManager.kNavigationBarHeight)
  78. manager.setZero = true
  79. manager.setFull = true
  80. manager.allChange = true
  81. manager.continues = true
  82. }
  83. open class func setBarColor(_ color:UIColor){
  84. sharedManager.barColor = color
  85. }
  86. open class func setTintColor(_ color:UIColor){
  87. sharedManager.tintColor = color
  88. sharedManager.selfNavigationBar.tintColor = color
  89. setTitleColorWithColor(color)
  90. //setTintColor(color)
  91. }
  92. open class func setBackgroudImage(_ image:UIImage){
  93. sharedManager.selfNavigationBar.setBackgroundImage(image, for: .default)
  94. }
  95. open class func setStatusBarStyle(_ style:UIStatusBarStyle){
  96. sharedManager.statusBarStyle = style
  97. UIApplication.shared.setStatusBarStyle(style, animated: true)
  98. }
  99. open class func setZeroAlphaOffset(_ offset:Float){
  100. sharedManager.zeroAlphaOffset = offset
  101. }
  102. open class func setFullAlphaOffset(_ offset:Float){
  103. sharedManager.fullAlphaOffset = offset
  104. }
  105. open class func setMaxAlphaValue(_ value:Float){
  106. let newValue = value > kMaxAlphaValue ? kMaxAlphaValue : value
  107. sharedManager.maxAlphaValue = newValue
  108. }
  109. open class func setMinAlphaValue(_ value:Float){
  110. let newValue = value < kMinAlphaValue ? kMinAlphaValue : value
  111. sharedManager.minAlphaValue = newValue
  112. }
  113. open class func setFullAlphaTintColor(_ color:UIColor){
  114. sharedManager.fullAlphaTintColor = color
  115. }
  116. open class func setFullAlphaBarStyle(_ style:UIStatusBarStyle){
  117. sharedManager.fullAlphaBarStyle = style
  118. }
  119. open class func setAllChange(_ allChange:Bool){
  120. sharedManager.allChange = allChange
  121. }
  122. open class func setReversal(_ reversal:Bool){
  123. sharedManager.reversal = reversal
  124. }
  125. open class func setContinus(_ continues:Bool){
  126. sharedManager.continues = continues
  127. }
  128. open class func managerWithController(_ viewController:UIViewController){
  129. let navigationBar = viewController.navigationController?.navigationBar
  130. sharedManager.saveIsTranslucent = (navigationBar?.isTranslucent)!
  131. sharedManager.selfNavigationController = viewController.navigationController
  132. sharedManager.selfNavigationBar = navigationBar
  133. sharedManager.selfNavigationBar.isTranslucent = true
  134. sharedManager.selfNavigationBar.setTitleVerticalPositionAdjustment(-100, for: .default)
  135. //保存原始数据
  136. saveOriginal(navigationBar!)
  137. navigationBar?.setBackgroundImage(UIImage(), for: .default)
  138. navigationBar?.shadowImage = UIImage()
  139. }
  140. open class func changeAlphaWithCurrentOffset(_ currentOffset:Float){
  141. let manager = sharedManager
  142. let currentAlpha = currentAlphaForOffset(currentOffset)
  143. if(!manager.barColor.isEqual(UIColor.clear)){
  144. if(!manager.continues){
  145. if(currentAlpha == manager.minAlphaValue){
  146. setNavigationBarColorWithAlpha(manager.minAlphaValue)
  147. }else if(currentAlpha == manager.maxAlphaValue){
  148. UIView.animate(withDuration: TimeInterval(kDefaultAnimationTime), animations: {
  149. setNavigationBarColorWithAlpha(manager.maxAlphaValue)
  150. })
  151. manager.setChange = true
  152. }else{
  153. if(manager.setChange){
  154. UIView.animate(withDuration: TimeInterval(kDefaultAnimationTime), animations: {
  155. setNavigationBarColorWithAlpha(manager.minAlphaValue)
  156. })
  157. manager.setChange = false
  158. }
  159. }
  160. }else{
  161. setNavigationBarColorWithAlpha(currentAlpha)
  162. }
  163. }
  164. if(manager.allChange) {
  165. changeTintColorWithOffset(currentAlpha)
  166. }
  167. }
  168. open class func reStoreToSystemNavigationBar(){
  169. sharedManager.selfNavigationBar.setBackgroundImage(sharedManager.saveImage, for: .default)
  170. //sharedManager.selfNavigationBar.isTranslucent = sharedManager.saveIsTranslucent
  171. sharedManager.selfNavigationBar.barTintColor = sharedManager.saveColor
  172. sharedManager.selfNavigationBar.tintColor = sharedManager.saveTintColor
  173. sharedManager.selfNavigationBar.titleTextAttributes = sharedManager.saveTitleAttributes
  174. sharedManager.selfNavigationBar.setTitleVerticalPositionAdjustment(0, for: .default)
  175. //sharedManager.selfNavigationController.setValue([UINavigationBar.init()], forKey: "navigationBar")
  176. //sharedManager.selfNavigationController.setValue([UINavigationBar()], forKey: "navigationBar")
  177. }
  178. private class func saveOriginal(_ navBar:UINavigationBar){
  179. sharedManager.saveImage = navBar.backgroundImage(for: .default)
  180. sharedManager.saveColor = navBar.barTintColor
  181. sharedManager.saveTintColor = navBar.tintColor
  182. sharedManager.saveTitleAttributes = navBar.titleTextAttributes ?? nil
  183. }
  184. private class func currentAlphaForOffset(_ offset:Float) -> Float{
  185. let manager = sharedManager
  186. var currentAlpha = (offset - manager.zeroAlphaOffset) / (manager.fullAlphaOffset - manager.zeroAlphaOffset)
  187. currentAlpha = currentAlpha < manager.minAlphaValue ? manager.minAlphaValue : (currentAlpha > manager.maxAlphaValue ? manager.maxAlphaValue : currentAlpha)
  188. currentAlpha = manager.reversal ? manager.maxAlphaValue + manager.minAlphaValue - currentAlpha : currentAlpha
  189. return currentAlpha
  190. }
  191. private class func changeTintColorWithOffset(_ currentAlpha:Float){
  192. let manager = sharedManager
  193. if (currentAlpha >= manager.maxAlphaValue && manager.fullAlphaTintColor != nil){
  194. if(manager.setFull){
  195. manager.setFull = false
  196. manager.setZero = true
  197. }else{
  198. if(manager.reversal){
  199. manager.setFull = true
  200. }
  201. return
  202. }
  203. manager.selfNavigationBar.tintColor = manager.fullAlphaTintColor
  204. setTitleColorWithColor(manager.fullAlphaTintColor)
  205. setUIStatusBarStyle(manager.fullAlphaBarStyle)
  206. }else if(manager.tintColor != nil){
  207. if(manager.setZero){
  208. manager.setZero = false
  209. manager.setFull = true
  210. }else{
  211. return
  212. }
  213. manager.selfNavigationBar.tintColor = manager.tintColor
  214. setTitleColorWithColor(manager.tintColor)
  215. setUIStatusBarStyle(manager.statusBarStyle)
  216. }
  217. }
  218. private class func setTitleColorWithColor(_ color:UIColor){
  219. if var textAttr = sharedManager.selfNavigationBar!.titleTextAttributes {
  220. textAttr[NSAttributedString.Key.foregroundColor] = color
  221. self.sharedManager.selfNavigationBar.titleTextAttributes = textAttr
  222. }else{
  223. self.sharedManager.selfNavigationBar.titleTextAttributes = [NSAttributedString.Key.foregroundColor:color]
  224. }
  225. }
  226. private class func setNavigationBarColorWithAlpha(_ alpha:Float){
  227. let manager = sharedManager
  228. setBackgroudImage(imageWithColor(manager.barColor.withAlphaComponent(CGFloat(alpha))))
  229. }
  230. private class func setUIStatusBarStyle(_ style:UIStatusBarStyle){
  231. UIApplication.shared.setStatusBarStyle(style, animated: true)
  232. }
  233. private class func imageWithColor(_ color:UIColor) -> UIImage{
  234. let rect = CGRect(x: 0, y: 0, width: 1, height: 1)
  235. UIGraphicsBeginImageContext(rect.size)
  236. let context = UIGraphicsGetCurrentContext()
  237. color.setFill()
  238. context?.fill(rect)
  239. let image = UIGraphicsGetImageFromCurrentImageContext()
  240. UIGraphicsEndImageContext()
  241. return image!
  242. }
  243. }