diff --git a/README.md b/README.md
index b1e02c2..242f9aa 100644
--- a/README.md
+++ b/README.md
@@ -1,9 +1,14 @@
+

[For Objective-C:https://github.com/wangrui460/WRNavigationBar](https://github.com/wangrui460/WRNavigationBar)
------------------------------------------------------------
+## iOS 技术交流
+我创建了一个 微信 iOS 技术交流群,欢迎小伙伴们加入一起交流学习~
+
+可以加我微信我拉你进去(备注iOS),我的微信号 wr1204607318
## Requirements
- iOS 8+
@@ -12,6 +17,10 @@
## Demo
+
+
+
+


@@ -22,6 +31,8 @@

+
+


@@ -34,6 +45,7 @@
## How To Use
+具体使用方法请参考Demo
// 一行代码搞定导航栏颜色
navBarBarTintColor = .white
@@ -45,6 +57,21 @@ 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
@@ -53,35 +80,59 @@ statusBarStyle = .default
## Update
+- **2017.12.09**
+解决问题:解决导航栏颜色和标题颜色改变失败的bug
-- **2017.05.12**
-解决问题:侧滑一点松开透明的导航栏会变不透明
+- **2017.12.09**
+解决问题:解决点击返回按钮导航栏标题颜色闪烁的问题
-- **2017.05.16**
-新增Demo:完成自定义导航栏实现透明渐变等效果
+- **2017.11.29**-
+更新:解决部分用户设置导航栏无效的问题~
-- **2017.05.20**
-解决问题:解决侧滑返回导航栏没有渐变动画太突兀的**问题
+- **2017.11.29**-
+更新:支持自定义导航栏~
-- **2017.05.21**
-解决问题:解决push导航栏没有渐变动画太突兀的问题
+- **2017.11.25**
+更新:更新到 Swift 4,适配iOS 11、iPhone X,自定义导航栏再等两天~
-- **2017.06.15**
-解决问题:解决scrollView正在滑动的时候,点击返回按钮,导航栏颜色变化突兀的问题
+- **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正在滑动的时候,点击返回按钮,导航栏颜色变化突兀的问题
-## Features
+- **2017.05.21**
+解决问题:解决push导航栏没有渐变动画太突兀的问题
+- **2017.05.20**
+解决问题:解决侧滑返回导航栏没有渐变动画太突兀的**问题
+
+- **2017.05.16**
+新增Demo:完成自定义导航栏实现透明渐变等效果
+
+- **2017.05.12**
+解决问题:侧滑一点松开透明的导航栏会变不透明
-# Contact me
-- Weibo: [@wangrui460](http://weibo.com/u/5145779726?is_all=1)
-- Email: wangruidev@gmail.com
-- QQ:1204607318
-# License
+## License
WRNavigationBar is available under the MIT license. See the LICENSE file for more info.
diff --git a/WRNavigationBar/WRCustomNavigationBar.swift b/WRNavigationBar/WRCustomNavigationBar.swift
new file mode 100644
index 0000000..5066e10
--- /dev/null
+++ b/WRNavigationBar/WRCustomNavigationBar.swift
@@ -0,0 +1,301 @@
+//
+// WRCustomNavigationBar.swift
+// WRNavigationBar_swift
+//
+// Created by itwangrui on 2017/11/25.
+// Copyright © 2017年 wangrui. All rights reserved.
+//
+
+import UIKit
+
+fileprivate let WRDefaultTitleSize:CGFloat = 18
+fileprivate let WRDefaultTitleColor = UIColor.black
+fileprivate let WRDefaultBackgroundColor = UIColor.white
+fileprivate let WRScreenWidth = UIScreen.main.bounds.size.width
+
+
+// MARK: - Router
+extension UIViewController
+{
+ // A页面 弹出 登录页面B
+ // presentedViewController: A页面
+ // presentingViewController: B页面
+
+ func wr_toLastViewController(animated:Bool)
+ {
+ if self.navigationController != nil
+ {
+ if self.navigationController?.viewControllers.count == 1
+ {
+ self.dismiss(animated: animated, completion: nil)
+ } else {
+ self.navigationController?.popViewController(animated: animated)
+ }
+ }
+ else if self.presentingViewController != nil {
+ self.dismiss(animated: animated, completion: nil)
+ }
+ }
+
+ class func wr_currentViewController() -> UIViewController
+ {
+ if let rootVC = UIApplication.shared.delegate?.window??.rootViewController {
+ return self.wr_currentViewController(from: rootVC)
+ } else {
+ return UIViewController()
+ }
+ }
+
+ class func wr_currentViewController(from fromVC:UIViewController) -> UIViewController
+ {
+ if fromVC.isKind(of: UINavigationController.self) {
+ let navigationController = fromVC as! UINavigationController
+ return wr_currentViewController(from: navigationController.viewControllers.last!)
+ }
+ else if fromVC.isKind(of: UITabBarController.self) {
+ let tabBarController = fromVC as! UITabBarController
+ return wr_currentViewController(from: tabBarController.selectedViewController!)
+ }
+ else if fromVC.presentedViewController != nil {
+ return wr_currentViewController(from:fromVC.presentingViewController!)
+ }
+ else {
+ return fromVC
+ }
+ }
+}
+
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////
+class WRCustomNavigationBar: UIView
+{
+ var onClickLeftButton:(()->())?
+ var onClickRightButton:(()->())?
+ var title:String? {
+ willSet {
+ titleLabel.isHidden = false
+ titleLabel.text = newValue
+ }
+ }
+ var titleLabelColor:UIColor? {
+ willSet {
+ titleLabel.textColor = newValue
+ }
+ }
+ var titleLabelFont:UIFont? {
+ willSet {
+ titleLabel.font = newValue
+ }
+ }
+ var barBackgroundColor:UIColor? {
+ willSet {
+ backgroundImageView.isHidden = true
+ backgroundView.isHidden = false
+ backgroundView.backgroundColor = newValue
+ }
+ }
+ var barBackgroundImage:UIImage? {
+ willSet {
+ backgroundView.isHidden = true
+ backgroundImageView.isHidden = false
+ backgroundImageView.image = newValue
+ }
+ }
+
+ // fileprivate UI variable
+ fileprivate lazy var titleLabel:UILabel = {
+ let label = UILabel()
+ label.textColor = WRDefaultTitleColor
+ label.font = UIFont.systemFont(ofSize: WRDefaultTitleSize)
+ label.textAlignment = .center
+ label.isHidden = true
+ return label
+ }()
+
+ fileprivate lazy var leftButton:UIButton = {
+ let button = UIButton()
+ button.imageView?.contentMode = .center
+ button.isHidden = true
+ button.addTarget(self, action: #selector(clickBack), for: .touchUpInside)
+ return button
+ }()
+
+ fileprivate lazy var rightButton:UIButton = {
+ let button = UIButton()
+ button.imageView?.contentMode = .center
+ button.isHidden = true
+ button.addTarget(self, action: #selector(clickRight), for: .touchUpInside)
+ return button
+ }()
+
+ fileprivate lazy var bottomLine:UIView = {
+ let view = UIView()
+ view.backgroundColor = UIColor(red: (218.0/255.0), green: (218.0/255.0), blue: (218.0/255.0), alpha: 1.0)
+ return view
+ }()
+
+ fileprivate lazy var backgroundView:UIView = {
+ let view = UIView()
+ return view
+ }()
+
+ fileprivate lazy var backgroundImageView:UIImageView = {
+ let imgView = UIImageView()
+ imgView.isHidden = true
+ return imgView
+ }()
+
+ // fileprivate other variable
+ fileprivate static var isIphoneX:Bool {
+ get {
+ return UIScreen.main.bounds.equalTo(CGRect(x: 0, y: 0, width: 375, height: 812))
+ }
+ }
+ fileprivate static var navBarBottom:Int {
+ get {
+ return isIphoneX ? 88 : 64
+ }
+ }
+
+ // init
+ class func CustomNavigationBar() -> WRCustomNavigationBar {
+ let frame = CGRect(x: 0, y: 0, width: WRScreenWidth, height: CGFloat(navBarBottom))
+ return WRCustomNavigationBar(frame: frame)
+ }
+ override init(frame: CGRect) {
+ super.init(frame: frame)
+ setupView()
+ }
+ required init?(coder aDecoder: NSCoder) {
+ super.init(coder: aDecoder)
+ setupView()
+ }
+
+ func setupView()
+ {
+ addSubview(backgroundView)
+ addSubview(backgroundImageView)
+ addSubview(leftButton)
+ addSubview(titleLabel)
+ addSubview(rightButton)
+ addSubview(bottomLine)
+ updateFrame()
+ backgroundColor = UIColor.clear
+ backgroundView.backgroundColor = WRDefaultBackgroundColor
+ }
+ func updateFrame()
+ {
+ let top:CGFloat = WRCustomNavigationBar.isIphoneX ? 44 : 20
+ let margin:CGFloat = 0
+ let buttonHeight:CGFloat = 44
+ let buttonWidth:CGFloat = 44
+ let titleLabelHeight:CGFloat = 44
+ let titleLabelWidth:CGFloat = 180
+
+ backgroundView.frame = self.bounds
+ backgroundImageView.frame = self.bounds
+ leftButton.frame = CGRect(x: margin, y: top, width: buttonWidth, height: buttonHeight)
+ rightButton.frame = CGRect(x: WRScreenWidth-buttonWidth-margin, y: top, width: buttonWidth, height: buttonHeight)
+ titleLabel.frame = CGRect(x: (WRScreenWidth-titleLabelWidth)/2.0, y: top, width: titleLabelWidth, height: titleLabelHeight)
+ bottomLine.frame = CGRect(x: 0, y: bounds.height-0.5, width: WRScreenWidth, height: 0.5)
+ }
+}
+
+
+extension WRCustomNavigationBar
+{
+ func wr_setBottomLineHidden(hidden:Bool) {
+ bottomLine.isHidden = hidden
+ }
+ func wr_setBackgroundAlpha(alpha:CGFloat) {
+ backgroundView.alpha = alpha
+ backgroundImageView.alpha = alpha
+ bottomLine.alpha = alpha
+ }
+ func wr_setTintColor(color:UIColor) {
+ leftButton.setTitleColor(color, for: .normal)
+ rightButton.setTitleColor(color, for: .normal)
+ titleLabel.textColor = color
+ }
+
+ // 左右按钮共有方法
+ func wr_setLeftButton(normal:UIImage, highlighted:UIImage) {
+ wr_setLeftButton(normal: normal, highlighted: highlighted, title: nil, titleColor: nil)
+ }
+ func wr_setLeftButton(image:UIImage) {
+ wr_setLeftButton(normal: image, highlighted: image, title: nil, titleColor: nil)
+ }
+ func wr_setLeftButton(title:String, titleColor:UIColor) {
+ wr_setLeftButton(normal: nil, highlighted: nil, title: title, titleColor: titleColor)
+ }
+
+ func wr_setRightButton(normal:UIImage, highlighted:UIImage) {
+ wr_setRightButton(normal: normal, highlighted: highlighted, title: nil, titleColor: nil)
+ }
+ func wr_setRightButton(image:UIImage) {
+ wr_setRightButton(normal: image, highlighted: image, title: nil, titleColor: nil)
+ }
+ func wr_setRightButton(title:String, titleColor:UIColor) {
+ wr_setRightButton(normal: nil, highlighted: nil, title: title, titleColor: titleColor)
+ }
+
+
+ // 左右按钮私有方法
+ private func wr_setLeftButton(normal:UIImage?, highlighted:UIImage?, title:String?, titleColor:UIColor?) {
+ leftButton.isHidden = false
+ leftButton.setImage(normal, for: .normal)
+ leftButton.setImage(highlighted, for: .highlighted)
+ leftButton.setTitle(title, for: .normal)
+ leftButton.setTitleColor(titleColor, for: .normal)
+ }
+ private func wr_setRightButton(normal:UIImage?, highlighted:UIImage?, title:String?, titleColor:UIColor?) {
+ rightButton.isHidden = false
+ rightButton.setImage(normal, for: .normal)
+ rightButton.setImage(highlighted, for: .highlighted)
+ rightButton.setTitle(title, for: .normal)
+ rightButton.setTitleColor(titleColor, for: .normal)
+ }
+}
+
+
+// MARK: - 导航栏左右按钮事件
+extension WRCustomNavigationBar
+{
+ @objc func clickBack() {
+ if let onClickBack = onClickLeftButton {
+ onClickBack()
+ } else {
+ let currentVC = UIViewController.wr_currentViewController()
+ currentVC.wr_toLastViewController(animated: true)
+ }
+ }
+ @objc func clickRight() {
+ if let onClickRight = onClickRightButton {
+ onClickRight()
+ }
+ }
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/WRNavigationBar/WRNavigationBar.swift b/WRNavigationBar/WRNavigationBar.swift
index c1af906..1322e4c 100644
--- a/WRNavigationBar/WRNavigationBar.swift
+++ b/WRNavigationBar/WRNavigationBar.swift
@@ -9,10 +9,11 @@
import UIKit
-extension UINavigationBar
+extension UINavigationBar:WRAwakeProtocol
{
fileprivate struct AssociatedKeys {
- static var backgroundView:UIView = UIView()
+ static var backgroundView: UIView = UIView()
+ static var backgroundImageView: UIImageView = UIImageView()
}
fileprivate var backgroundView:UIView? {
@@ -27,14 +28,46 @@ extension UINavigationBar
}
}
+ 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: 64))
+ 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)
}
@@ -44,8 +77,17 @@ extension UINavigationBar
// set _UIBarBackground alpha (_UIBarBackground subviews alpha <= _UIBarBackground alpha)
fileprivate func wr_setBackgroundAlpha(alpha:CGFloat)
{
- let barBackgroundView = subviews[0]
- barBackgroundView.alpha = alpha
+ 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的透明度
@@ -104,15 +146,73 @@ extension UINavigationBar
{
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
+extension UINavigationController: WRFatherAwakeProtocol
{
override open var preferredStatusBarStyle: UIStatusBarStyle {
- return topViewController?.statusBarStyle ?? UIColor.defaultStatusBarStyle
+ return topViewController?.statusBarStyle ?? WRNavigationBar.defaultStatusBarStyle
+ }
+
+ fileprivate func setNeedsNavigationBarUpdate(backgroundImage: UIImage)
+ {
+ navigationBar.wr_setBackgroundImage(image: backgroundImage)
}
fileprivate func setNeedsNavigationBarUpdate(barTintColor: UIColor)
@@ -128,43 +228,55 @@ extension UINavigationController
fileprivate func setNeedsNavigationBarUpdate(tintColor: UIColor) {
navigationBar.tintColor = tintColor
}
+
+ fileprivate func setNeedsNavigationBarUpdate(hideShadowImage: Bool)
+ {
+ navigationBar.shadowImage = (hideShadowImage == true) ? UIImage() : nil
+ }
- fileprivate func setNeedsNavigationBarUpdate(titleColor: UIColor) {
- navigationBar.titleTextAttributes = [NSForegroundColorAttributeName:titleColor]
+ 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 ?? .defaultNavBarBarTintColor
- let toBarTintColor = toVC?.navBarBarTintColor ?? .defaultNavBarBarTintColor
- let newBarTintColor = UIColor.middleColor(fromColor: fromBarTintColor, toColor: toBarTintColor, percent: progress)
+ 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)
// change navBarTintColor
- let fromTintColor = fromVC?.navBarTintColor ?? .defaultNavBarTintColor
- let toTintColor = toVC?.navBarTintColor ?? .defaultNavBarTintColor
- let newTintColor = UIColor.middleColor(fromColor: fromTintColor, toColor: toTintColor, percent: progress)
+ 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)
// change navBarTitleColor
- let fromTitleColor = fromVC?.navBarTitleColor ?? .defaultNavBarTitleColor
- let toTitleColor = toVC?.navBarTitleColor ?? .defaultNavBarTitleColor
- let newTitleColor = UIColor.middleColor(fromColor: fromTitleColor, toColor: toTitleColor, percent: progress)
- setNeedsNavigationBarUpdate(titleColor: newTitleColor)
+// 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 ?? UIColor.defaultBackgroundAlpha
- let toBarBackgroundAlpha = toVC?.navBarBackgroundAlpha ?? UIColor.defaultBackgroundAlpha
- let newBarBackgroundAlpha = UIColor.middleAlpha(fromAlpha: fromBarBackgroundAlpha, toAlpha: toBarBackgroundAlpha, percent: progress)
+ 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
- open override class func initialize()
+ public static func fatherAwake()
{
- guard self == UINavigationController.self else { return }
DispatchQueue.once(token: onceToken)
{
let needSwizzleSelectorArr = [
@@ -173,13 +285,14 @@ extension UINavigationController
#selector(popToRootViewController),
#selector(pushViewController)
]
-
+
for selector in needSwizzleSelectorArr {
// _updateInteractiveTransition: => wr_updateInteractiveTransition:
let str = ("wr_" + selector.description).replacingOccurrences(of: "__", with: "_")
- let originalMethod = class_getInstanceMethod(self, selector)
- let swizzledMethod = class_getInstanceMethod(self, Selector(str))
- method_exchangeImplementations(originalMethod, swizzledMethod)
+ if let originalMethod = class_getInstanceMethod(self, selector),
+ let swizzledMethod = class_getInstanceMethod(self, Selector(str)) {
+ method_exchangeImplementations(originalMethod, swizzledMethod)
+ }
}
}
}
@@ -198,8 +311,9 @@ extension UINavigationController
}
// swizzling system method: popToViewController
- func wr_popToViewController(_ viewController: UIViewController, animated: Bool) -> [UIViewController]?
+ @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
@@ -217,7 +331,7 @@ extension UINavigationController
}
// swizzling system method: popToRootViewControllerAnimated
- func wr_popToRootViewControllerAnimated(_ animated: Bool) -> [UIViewController]?
+ @objc func wr_popToRootViewControllerAnimated(_ animated: Bool) -> [UIViewController]?
{
var displayLink:CADisplayLink? = CADisplayLink(target: self, selector: #selector(popNeedDisplay))
displayLink?.add(to: RunLoop.main, forMode: .commonModes)
@@ -234,7 +348,7 @@ extension UINavigationController
}
// change navigationBar barTintColor smooth before pop to current VC finished
- func popNeedDisplay()
+ @objc fileprivate func popNeedDisplay()
{
guard let topViewController = topViewController,
let coordinator = topViewController.transitionCoordinator else {
@@ -264,10 +378,10 @@ extension UINavigationController
}
// swizzling system method: pushViewController
- func wr_pushViewController(_ viewController: UIViewController, animated: Bool)
+ @objc func wr_pushViewController(_ viewController: UIViewController, animated: Bool)
{
var displayLink:CADisplayLink? = CADisplayLink(target: self, selector: #selector(pushNeedDisplay))
- displayLink?.add(to: RunLoop.main, forMode: .defaultRunLoopMode)
+ displayLink?.add(to: RunLoop.main, forMode: .commonModes)
CATransaction.setCompletionBlock {
displayLink?.invalidate()
displayLink = nil
@@ -281,7 +395,7 @@ extension UINavigationController
}
// change navigationBar barTintColor smooth before push to current VC finished or before pop to current VC finished
- func pushNeedDisplay()
+ @objc fileprivate func pushNeedDisplay()
{
guard let topViewController = topViewController,
let coordinator = topViewController.transitionCoordinator else {
@@ -330,8 +444,8 @@ extension UINavigationController: UINavigationBarDelegate
private func dealInteractionChanges(_ context: UIViewControllerTransitionCoordinatorContext)
{
let animations: (UITransitionContextViewControllerKey) -> () = {
- let curColor = context.viewController(forKey: $0)?.navBarBarTintColor ?? UIColor.defaultNavBarBarTintColor
- let curAlpha = context.viewController(forKey: $0)?.navBarBackgroundAlpha ?? UIColor.defaultBackgroundAlpha
+ 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)
@@ -356,7 +470,7 @@ extension UINavigationController: UINavigationBarDelegate
}
// swizzling system method: _updateInteractiveTransition
- func wr_updateInteractiveTransition(_ percentComplete: CGFloat)
+ @objc func wr_updateInteractiveTransition(_ percentComplete: CGFloat)
{
guard let topViewController = topViewController,
let coordinator = topViewController.transitionCoordinator else {
@@ -375,24 +489,27 @@ extension UINavigationController: UINavigationBarDelegate
//=============================================================================
// MARK: - store navigationBar barTintColor and tintColor every viewController
//=============================================================================
-extension UIViewController
+extension UIViewController: WRAwakeProtocol
{
fileprivate struct AssociatedKeys
{
static var pushToCurrentVCFinished: Bool = false
static var pushToNextVCFinished:Bool = false
- static var navBarBarTintColor: UIColor = UIColor.defaultNavBarBarTintColor
+ static var navBarBackgroundImage: UIImage = UIImage()
+
+ static var navBarBarTintColor: UIColor = WRNavigationBar.defaultNavBarBarTintColor
static var navBarBackgroundAlpha:CGFloat = 1.0
- static var navBarTintColor: UIColor = UIColor.defaultNavBarTintColor
- static var navBarTitleColor: UIColor = UIColor.defaultNavBarTitleColor
+ static var navBarTintColor: UIColor = WRNavigationBar.defaultNavBarTintColor
+ static var navBarTitleColor: UIColor = WRNavigationBar.defaultNavBarTitleColor
static var statusBarStyle: 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
- var pushToCurrentVCFinished:Bool {
+ fileprivate var pushToCurrentVCFinished:Bool {
get {
guard let isFinished = objc_getAssociatedObject(self, &AssociatedKeys.pushToCurrentVCFinished) as? Bool else {
return false
@@ -405,7 +522,7 @@ extension UIViewController
}
// navigationBar barTintColor can not change by currentVC when currentVC push to nextVC finished
- var pushToNextVCFinished:Bool {
+ fileprivate var pushToNextVCFinished:Bool {
get {
guard let isFinished = objc_getAssociatedObject(self, &AssociatedKeys.pushToNextVCFinished) as? Bool else {
return false
@@ -417,11 +534,31 @@ extension UIViewController
}
}
+ // 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 {
guard let barTintColor = objc_getAssociatedObject(self, &AssociatedKeys.navBarBarTintColor) as? UIColor else {
- return UIColor.defaultNavBarBarTintColor
+ return WRNavigationBar.defaultNavBarBarTintColor
}
return barTintColor
}
@@ -429,12 +566,11 @@ extension UIViewController
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)
+// let navBar = customNavBar as! UINavigationBar
+// navBar.wr_setBackgroundColor(color: newValue)
}
- else
- {
- if pushToCurrentVCFinished == true && pushToNextVCFinished == false {
+ else {
+ if canUpdateNavBarBarTintColorOrBackgroundAlpha == true {
navigationController?.setNeedsNavigationBarUpdate(barTintColor: newValue)
}
}
@@ -453,23 +589,32 @@ extension UIViewController
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)
+// let navBar = customNavBar as! UINavigationBar
+// navBar.wr_setBackgroundAlpha(alpha: newValue)
}
- else
- {
- if pushToCurrentVCFinished == true && pushToNextVCFinished == false {
+ 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 {
guard let tintColor = objc_getAssociatedObject(self, &AssociatedKeys.navBarTintColor) as? UIColor else {
- return UIColor.defaultNavBarTintColor
+ return WRNavigationBar.defaultNavBarTintColor
}
return tintColor
}
@@ -477,8 +622,8 @@ extension UIViewController
objc_setAssociatedObject(self, &AssociatedKeys.navBarTintColor, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
if customNavBar.isKind(of: UINavigationBar.self) {
- let navBar = customNavBar as! UINavigationBar
- navBar.tintColor = newValue
+// let navBar = customNavBar as! UINavigationBar
+// navBar.tintColor = newValue
}
else
{
@@ -493,7 +638,7 @@ extension UIViewController
var navBarTitleColor: UIColor {
get {
guard let titleColor = objc_getAssociatedObject(self, &AssociatedKeys.navBarTitleColor) as? UIColor else {
- return UIColor.defaultNavBarTitleColor
+ return WRNavigationBar.defaultNavBarTitleColor
}
return titleColor
}
@@ -501,8 +646,8 @@ extension UIViewController
objc_setAssociatedObject(self, &AssociatedKeys.navBarTitleColor, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
if customNavBar.isKind(of: UINavigationBar.self) {
- let navBar = customNavBar as! UINavigationBar
- navBar.titleTextAttributes = [NSForegroundColorAttributeName:newValue]
+// let navBar = customNavBar as! UINavigationBar
+// navBar.titleTextAttributes = [NSAttributedStringKey.foregroundColor:newValue]
}
else
{
@@ -517,7 +662,7 @@ extension UIViewController
var statusBarStyle: UIStatusBarStyle {
get {
guard let style = objc_getAssociatedObject(self, &AssociatedKeys.statusBarStyle) as? UIStatusBarStyle else {
- return UIColor.defaultStatusBarStyle
+ return WRNavigationBar.defaultStatusBarStyle
}
return style
}
@@ -527,6 +672,20 @@ extension UIViewController
}
}
+ // 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 {
@@ -542,12 +701,8 @@ extension UIViewController
// swizzling two system methods: viewWillAppear(_:) and viewWillDisappear(_:)
private static let onceToken = UUID().uuidString
- open override class func initialize()
+ @objc public static func wrAwake()
{
- guard self == UIViewController.self else {
- return
- }
-
DispatchQueue.once(token: onceToken)
{
let needSwizzleSelectors = [
@@ -555,39 +710,72 @@ extension UIViewController
#selector(viewWillDisappear(_:)),
#selector(viewDidAppear(_:))
]
-
+
for selector in needSwizzleSelectors
{
let newSelectorStr = "wr_" + selector.description
- let originalMethod = class_getInstanceMethod(self, selector)
- let swizzledMethod = class_getInstanceMethod(self, Selector(newSelectorStr))
- method_exchangeImplementations(originalMethod, swizzledMethod)
+ if let originalMethod = class_getInstanceMethod(self, selector),
+ let swizzledMethod = class_getInstanceMethod(self, Selector(newSelectorStr)) {
+ method_exchangeImplementations(originalMethod, swizzledMethod)
+ }
}
}
}
- func wr_viewWillAppear(_ animated: Bool)
+ @objc func wr_viewWillAppear(_ animated: Bool)
{
- pushToNextVCFinished = false
- navigationController?.setNeedsNavigationBarUpdate(tintColor: navBarTintColor)
- navigationController?.setNeedsNavigationBarUpdate(titleColor: navBarTitleColor)
+ if canUpdateNavigationBar() == true {
+ pushToNextVCFinished = false
+ navigationController?.setNeedsNavigationBarUpdate(tintColor: navBarTintColor)
+ navigationController?.setNeedsNavigationBarUpdate(titleColor: navBarTitleColor)
+ }
wr_viewWillAppear(animated)
}
- func wr_viewWillDisappear(_ animated: Bool)
+ @objc func wr_viewWillDisappear(_ animated: Bool)
{
- pushToNextVCFinished = true
+ if canUpdateNavigationBar() == true {
+ pushToNextVCFinished = true
+ }
wr_viewWillDisappear(animated)
}
- func wr_viewDidAppear(_ animated: Bool)
+ @objc func wr_viewDidAppear(_ animated: Bool)
{
- navigationController?.setNeedsNavigationBarUpdate(barTintColor: navBarBarTintColor)
- navigationController?.setNeedsNavigationBarUpdate(barBackgroundAlpha: navBarBackgroundAlpha)
- navigationController?.setNeedsNavigationBarUpdate(tintColor: navBarTintColor)
- navigationController?.setNeedsNavigationBarUpdate(titleColor: navBarTitleColor)
+
+ 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
+ {
+ 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
+ }
+ }
+
}
//====================================================================================
@@ -618,15 +806,18 @@ extension DispatchQueue {
//===========================================================================================
// MARK: - default navigationBar barTintColor、tintColor and statusBarStyle YOU CAN CHANGE!!!
//===========================================================================================
-extension UIColor
+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 {
@@ -639,6 +830,18 @@ extension UIColor
}
}
+ 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 {
@@ -675,6 +878,18 @@ extension UIColor
}
}
+ 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
@@ -714,8 +929,76 @@ extension UIColor
}
}
+extension WRNavigationBar
+{
+ class func isIphoneX() -> Bool {
+ return UIScreen.main.bounds.equalTo(CGRect(x: 0, y: 0, width: 375, height: 812))
+ }
+ 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.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)
+ 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 方法
+
diff --git a/WRNavigationBar_swift/Podfile b/WRNavigationBar_swift/Podfile
index 4caf475..81b4c14 100644
--- a/WRNavigationBar_swift/Podfile
+++ b/WRNavigationBar_swift/Podfile
@@ -1,13 +1,4 @@
-# Uncomment this line to define a global platform for your project
-#官方Cocoapods的源
-#source 'https://github.com/CocoaPods/Specs.git'
-
-#本地私有源
-#source 'https://git.oschina.net/scx/JLSpecs.git'
-
-# 本项目地址
-#source https://github.com/wangrui460
# 修改过得第三方库
diff --git a/WRNavigationBar_swift/Podfile.lock b/WRNavigationBar_swift/Podfile.lock
index a57cf55..c6c2166 100644
--- a/WRNavigationBar_swift/Podfile.lock
+++ b/WRNavigationBar_swift/Podfile.lock
@@ -1,12 +1,12 @@
PODS:
- - Kingfisher (3.6.2)
+ - Kingfisher (4.3.1)
DEPENDENCIES:
- Kingfisher
SPEC CHECKSUMS:
- Kingfisher: 2c94e72c6830622c71d06adf4ea024c37d316830
+ Kingfisher: 75541c4b62f02e1fde6f9772303de3d9ebe8f5b3
PODFILE CHECKSUM: eedd5593b4e862f4a6b0ebf6fd6f3f022a9f6b1d
-COCOAPODS: 1.2.1
+COCOAPODS: 1.3.1
diff --git a/WRNavigationBar_swift/Pods/Kingfisher/README.md b/WRNavigationBar_swift/Pods/Kingfisher/README.md
index bd3c0f1..b696677 100644
--- a/WRNavigationBar_swift/Pods/Kingfisher/README.md
+++ b/WRNavigationBar_swift/Pods/Kingfisher/README.md
@@ -7,12 +7,12 @@
-
-
+
+
Kingfisher is a lightweight, pure-Swift library for downloading and caching images from the web. This project is heavily inspired by the popular [SDWebImage](https://github.com/rs/SDWebImage). It provides you a chance to use a pure-Swift alternative in your next app.
@@ -27,6 +27,7 @@ Kingfisher is a lightweight, pure-Swift library for downloading and caching imag
- [x] Prefetching images and showing them from cache later when necessary.
- [x] Extensions for `UIImageView`, `NSImage` and `UIButton` to directly set an image from a URL.
- [x] Built-in transition animation when setting images.
+- [x] Customizable placeholder while loading images.
- [x] Extensible image processing and image format support.
The simplest use-case is setting an image to an image view with the `UIImageView` extension:
@@ -41,11 +42,12 @@ Kingfisher will download the image from `url`, send it to both the memory cache
## Requirements
- iOS 8.0+ / macOS 10.10+ / tvOS 9.0+ / watchOS 2.0+
-- Swift 3 (Kingfisher 3.x), Swift 2.3 (Kingfisher 2.x)
+- Swift 4 (Kingfisher 4.x), Swift 3 (Kingfisher 3.x)
-Main development of Kingfisher will support Swift 3. Only critical bug fixes will be made for Kingfisher 2.x.
+Main development of Kingfisher is based on Swift 4. Only critical bug fixes will be applied to Kingfisher 3.x.
-[Kingfisher 3.0 Migration Guide](https://github.com/onevcat/Kingfisher/wiki/Kingfisher-3.0-Migration-Guide) - If you are upgrading to Kingfisher 3.x from an earlier version, please read this for more information.
+- Kingfisher 4.0 Migration - Kingfisher 3.x should be source compatible to Kingfisher 4. The reason for a major update is that we need to specify the Swift version explicitly for Xcode. All deprecated methods in Kingfisher 3 has been removed, so please ensure you have no warning left before you migrate from Kingfisher 3 to Kingfisher 4. If you have any trouble in migrating, please open an issue to discuss.
+- [Kingfisher 3.0 Migration Guide](https://github.com/onevcat/Kingfisher/wiki/Kingfisher-3.0-Migration-Guide) - If you are upgrading to Kingfisher 3.x from an earlier version, please read this for more information.
## Next Steps
@@ -75,6 +77,36 @@ The logo of Kingfisher is inspired by [Tangram (七巧板)](http://en.wikipedia.
Follow and contact me on [Twitter](http://twitter.com/onevcat) or [Sina Weibo](http://weibo.com/onevcat). If you find an issue, just [open a ticket](https://github.com/onevcat/Kingfisher/issues/new). Pull requests are warmly welcome as well.
+## Contributors
+
+This project exists thanks to all the people who contribute. [[Contribute]](https://github.com/onevcat/Kingfisher/blob/master/CONTRIBUTING.md).
+
+
+
+## Backers
+
+Thank you to all our backers! 🙏 [[Become a backer](https://opencollective.com/Kingfisher#backer)]
+
+
+
+
+## Sponsors
+
+Support this project by becoming a sponsor. Your logo will show up here with a link to your website. [[Become a sponsor](https://opencollective.com/Kingfisher#sponsor)]
+
+
+
+
+
+
+
+
+
+
+
+
+
+
### License
Kingfisher is released under the MIT license. See LICENSE for details.
diff --git a/WRNavigationBar_swift/Pods/Kingfisher/Sources/AnimatedImageView.swift b/WRNavigationBar_swift/Pods/Kingfisher/Sources/AnimatedImageView.swift
index 5ea04dc..df65bff 100755
--- a/WRNavigationBar_swift/Pods/Kingfisher/Sources/AnimatedImageView.swift
+++ b/WRNavigationBar_swift/Pods/Kingfisher/Sources/AnimatedImageView.swift
@@ -149,12 +149,12 @@ open class AnimatedImageView: UIImageView {
super.didMoveToSuperview()
didMove()
}
-
- // This is for back compatibility that using regular UIImageView to show GIF.
- override func shouldPreloadAllGIF() -> Bool {
+
+ // This is for back compatibility that using regular UIImageView to show animated image.
+ override func shouldPreloadAllAnimation() -> Bool {
return false
}
-
+
// MARK: - Private method
/// Reset the animator.
private func reset() {
@@ -179,7 +179,25 @@ open class AnimatedImageView: UIImageView {
/// Update the current frame with the displayLink duration.
private func updateFrame() {
- if animator?.updateCurrentFrame(duration: displayLink.duration) ?? false {
+ let duration: CFTimeInterval
+
+ // CA based display link is opt-out from ProMotion by default.
+ // So the duration and its FPS might not match.
+ // See [#718](https://github.com/onevcat/Kingfisher/issues/718)
+ if #available(iOS 10.0, tvOS 10.0, *) {
+ // By setting CADisableMinimumFrameDuration to YES in Info.plist may
+ // cause the preferredFramesPerSecond being 0
+ if displayLink.preferredFramesPerSecond == 0 {
+ duration = displayLink.duration
+ } else {
+ // Some devices (like iPad Pro 10.5) will have a different FPS.
+ duration = 1.0 / Double(displayLink.preferredFramesPerSecond)
+ }
+ } else {
+ duration = displayLink.duration
+ }
+
+ if animator?.updateCurrentFrame(duration: duration) ?? false {
layer.setNeedsDisplay()
}
}
@@ -208,7 +226,7 @@ class Animator {
fileprivate var timeSinceLastFrameChange: TimeInterval = 0.0
fileprivate var needsPrescaling = true
- /// Loop count of animatd image.
+ /// Loop count of animated image.
private var loopCount = 0
var currentFrame: UIImage? {
diff --git a/WRNavigationBar_swift/Pods/Kingfisher/Sources/CacheSerializer.swift b/WRNavigationBar_swift/Pods/Kingfisher/Sources/CacheSerializer.swift
index 8d8cdc9..9d4ec7d 100644
--- a/WRNavigationBar_swift/Pods/Kingfisher/Sources/CacheSerializer.swift
+++ b/WRNavigationBar_swift/Pods/Kingfisher/Sources/CacheSerializer.swift
@@ -64,7 +64,7 @@ public struct DefaultCacheSerializer: CacheSerializer {
public func data(with image: Image, original: Data?) -> Data? {
let imageFormat = original?.kf.imageFormat ?? .unknown
-
+
let data: Data?
switch imageFormat {
case .PNG: data = image.kf.pngRepresentation()
@@ -72,7 +72,7 @@ public struct DefaultCacheSerializer: CacheSerializer {
case .GIF: data = image.kf.gifRepresentation()
case .unknown: data = original ?? image.kf.normalized.kf.pngRepresentation()
}
-
+
return data
}
@@ -81,7 +81,7 @@ public struct DefaultCacheSerializer: CacheSerializer {
return Kingfisher.image(
data: data,
scale: options.scaleFactor,
- preloadAllGIFData: options.preloadAllGIFData,
+ preloadAllAnimationData: options.preloadAllAnimationData,
onlyFirstFrame: options.onlyLoadFirstFrame)
}
}
diff --git a/WRNavigationBar_swift/Pods/Kingfisher/Sources/Filter.swift b/WRNavigationBar_swift/Pods/Kingfisher/Sources/Filter.swift
index 5f20987..b2f4504 100644
--- a/WRNavigationBar_swift/Pods/Kingfisher/Sources/Filter.swift
+++ b/WRNavigationBar_swift/Pods/Kingfisher/Sources/Filter.swift
@@ -71,23 +71,32 @@ public struct Filter {
let filter = CIFilter(name: "CISourceOverCompositing")!
filter.setValue(colorImage, forKey: kCIInputImageKey)
filter.setValue(input, forKey: kCIInputBackgroundImageKey)
+ #if swift(>=4.0)
+ return filter.outputImage?.cropped(to: input.extent)
+ #else
return filter.outputImage?.cropping(to: input.extent)
+ #endif
}
}
public typealias ColorElement = (CGFloat, CGFloat, CGFloat, CGFloat)
/// Color control filter which will apply color control change to images.
- public static var colorControl: (ColorElement) -> Filter = {
- brightness, contrast, saturation, inputEV in
- Filter { input in
+ public static var colorControl: (ColorElement) -> Filter = { arg -> Filter in
+ let (brightness, contrast, saturation, inputEV) = arg
+ return Filter { input in
let paramsColor = [kCIInputBrightnessKey: brightness,
kCIInputContrastKey: contrast,
kCIInputSaturationKey: saturation]
- let blackAndWhite = input.applyingFilter("CIColorControls", withInputParameters: paramsColor)
let paramsExposure = [kCIInputEVKey: inputEV]
+ #if swift(>=4.0)
+ let blackAndWhite = input.applyingFilter("CIColorControls", parameters: paramsColor)
+ return blackAndWhite.applyingFilter("CIExposureAdjust", parameters: paramsExposure)
+ #else
+ let blackAndWhite = input.applyingFilter("CIColorControls", withInputParameters: paramsColor)
return blackAndWhite.applyingFilter("CIExposureAdjust", withInputParameters: paramsExposure)
+ #endif
}
}
@@ -126,20 +135,3 @@ extension Kingfisher where Base: Image {
}
}
-
-public extension Image {
-
- /// Apply a `Filter` containing `CIImage` transformer to `self`.
- ///
- /// - parameter filter: The filter used to transform `self`.
- ///
- /// - returns: A transformed image by input `Filter`.
- ///
- /// - Note: Only CG-based images are supported. If any error happens during transforming, `self` will be returned.
- @available(*, deprecated,
- message: "Extensions directly on Image are deprecated. Use `kf.apply` instead.",
- renamed: "kf.apply")
- public func kf_apply(_ filter: Filter) -> Image {
- return kf.apply(filter)
- }
-}
diff --git a/WRNavigationBar_swift/Pods/Kingfisher/Sources/FormatIndicatedCacheSerializer.swift b/WRNavigationBar_swift/Pods/Kingfisher/Sources/FormatIndicatedCacheSerializer.swift
new file mode 100644
index 0000000..9014e37
--- /dev/null
+++ b/WRNavigationBar_swift/Pods/Kingfisher/Sources/FormatIndicatedCacheSerializer.swift
@@ -0,0 +1,96 @@
+//
+// RequestModifier.swift
+// Kingfisher
+//
+// Created by Junyu Kuang on 5/28/17.
+//
+// Copyright (c) 2017 Wei Wang
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+import Foundation
+
+/// `FormatIndicatedCacheSerializer` let you indicate an image format for serialized caches.
+///
+/// It could serialize and deserialize PNG, JEPG and GIF images. For
+/// image other than these formats, a normalized `pngRepresentation` will be used.
+///
+/// Example:
+/// ````
+/// private let profileImageSize = CGSize(width: 44, height: 44)
+///
+/// private let imageProcessor = RoundCornerImageProcessor(
+/// cornerRadius: profileImageSize.width / 2, targetSize: profileImageSize)
+///
+/// private let optionsInfo: KingfisherOptionsInfo = [
+/// .cacheSerializer(FormatIndicatedCacheSerializer.png),
+/// .backgroundDecode, .processor(imageProcessor), .scaleFactor(UIScreen.main.scale)]
+///
+/// extension UIImageView {
+/// func setProfileImage(with url: URL) {
+/// // Image will always cached as PNG format to preserve alpha channel for round rect.
+/// _ = kf.setImage(with: url, options: optionsInfo)
+/// }
+///}
+/// ````
+public struct FormatIndicatedCacheSerializer: CacheSerializer {
+
+ public static let png = FormatIndicatedCacheSerializer(imageFormat: .PNG)
+ public static let jpeg = FormatIndicatedCacheSerializer(imageFormat: .JPEG)
+ public static let gif = FormatIndicatedCacheSerializer(imageFormat: .GIF)
+
+ /// The indicated image format.
+ private let imageFormat: ImageFormat
+
+ public func data(with image: Image, original: Data?) -> Data? {
+
+ func imageData(withFormat imageFormat: ImageFormat) -> Data? {
+ switch imageFormat {
+ case .PNG: return image.kf.pngRepresentation()
+ case .JPEG: return image.kf.jpegRepresentation(compressionQuality: 1.0)
+ case .GIF: return image.kf.gifRepresentation()
+ case .unknown: return nil
+ }
+ }
+
+ // generate data with indicated image format
+ if let data = imageData(withFormat: imageFormat) {
+ return data
+ }
+
+ let originalFormat = original?.kf.imageFormat ?? .unknown
+
+ // generate data with original image's format
+ if originalFormat != imageFormat, let data = imageData(withFormat: originalFormat) {
+ return data
+ }
+
+ return original ?? image.kf.normalized.kf.pngRepresentation()
+ }
+
+ /// Same implementation as `DefaultCacheSerializer`.
+ public func image(with data: Data, options: KingfisherOptionsInfo?) -> Image? {
+ let options = options ?? KingfisherEmptyOptionsInfo
+ return Kingfisher.image(
+ data: data,
+ scale: options.scaleFactor,
+ preloadAllAnimationData: options.preloadAllAnimationData,
+ onlyFirstFrame: options.onlyLoadFirstFrame)
+ }
+}
diff --git a/WRNavigationBar_swift/Pods/Kingfisher/Sources/Image.swift b/WRNavigationBar_swift/Pods/Kingfisher/Sources/Image.swift
index c132523..5e0aaf4 100755
--- a/WRNavigationBar_swift/Pods/Kingfisher/Sources/Image.swift
+++ b/WRNavigationBar_swift/Pods/Kingfisher/Sources/Image.swift
@@ -179,7 +179,7 @@ extension Kingfisher where Base: Image {
return nil
}
let rep = NSBitmapImageRep(cgImage: cgimage)
- return rep.representation(using: .PNG, properties: [:])
+ return rep.representation(using: .png, properties: [:])
#else
return UIImagePNGRepresentation(base)
#endif
@@ -192,7 +192,7 @@ extension Kingfisher where Base: Image {
return nil
}
let rep = NSBitmapImageRep(cgImage: cgImage)
- return rep.representation(using:.JPEG, properties: [NSImageCompressionFactor: compressionQuality])
+ return rep.representation(using:.jpeg, properties: [.compressionFactor: compressionQuality])
#else
return UIImageJPEGRepresentation(base, compressionQuality)
#endif
@@ -292,10 +292,10 @@ extension Kingfisher where Base: Image {
return image
#endif
}
-
- static func image(data: Data, scale: CGFloat, preloadAllGIFData: Bool, onlyFirstFrame: Bool) -> Image? {
+
+ static func image(data: Data, scale: CGFloat, preloadAllAnimationData: Bool, onlyFirstFrame: Bool) -> Image? {
var image: Image?
-
+
#if os(macOS)
switch data.kf.imageFormat {
case .JPEG:
@@ -307,7 +307,7 @@ extension Kingfisher where Base: Image {
with: data,
scale: scale,
duration: 0.0,
- preloadAll: preloadAllGIFData,
+ preloadAll: preloadAllAnimationData,
onlyFirstFrame: onlyFirstFrame)
case .unknown:
image = Image(data: data)
@@ -323,13 +323,13 @@ extension Kingfisher where Base: Image {
with: data,
scale: scale,
duration: 0.0,
- preloadAll: preloadAllGIFData,
+ preloadAll: preloadAllAnimationData,
onlyFirstFrame: onlyFirstFrame)
case .unknown:
image = Image(data: data, scale: scale)
}
#endif
-
+
return image
}
}
@@ -340,14 +340,19 @@ extension Kingfisher where Base: Image {
// MARK: - Round Corner
/// Create a round corner image based on `self`.
///
- /// - parameter radius: The round corner radius of creating image.
- /// - parameter size: The target size of creating image.
+ /// - parameter radius: The round corner radius of creating image.
+ /// - parameter size: The target size of creating image.
+ /// - parameter corners: The target corners which will be applied rounding.
+ /// - parameter backgroundColor: The background color for the output image
///
/// - returns: An image with round corner of `self`.
///
/// - Note: This method only works for CG-based image.
- public func image(withRoundRadius radius: CGFloat, fit size: CGSize) -> Image {
-
+ public func image(withRoundRadius radius: CGFloat,
+ fit size: CGSize,
+ roundingCorners corners: RectCorner = .all,
+ backgroundColor: Color? = nil) -> Image
+ {
guard let cgImage = cgImage else {
assertionFailure("[Kingfisher] Round corner image only works for CG-based image.")
return base
@@ -356,7 +361,13 @@ extension Kingfisher where Base: Image {
let rect = CGRect(origin: CGPoint(x: 0, y: 0), size: size)
return draw(cgImage: cgImage, to: size) {
#if os(macOS)
- let path = NSBezierPath(roundedRect: rect, xRadius: radius, yRadius: radius)
+ if let backgroundColor = backgroundColor {
+ let rectPath = NSBezierPath(rect: rect)
+ backgroundColor.setFill()
+ rectPath.fill()
+ }
+
+ let path = NSBezierPath(roundedRect: rect, byRoundingCorners: corners, radius: radius)
path.windingRule = .evenOddWindingRule
path.addClip()
base.draw(in: rect)
@@ -365,7 +376,16 @@ extension Kingfisher where Base: Image {
assertionFailure("[Kingfisher] Failed to create CG context for image.")
return
}
- let path = UIBezierPath(roundedRect: rect, byRoundingCorners: .allCorners, cornerRadii: CGSize(width: radius, height: radius)).cgPath
+
+ if let backgroundColor = backgroundColor {
+ let rectPath = UIBezierPath(rect: rect)
+ backgroundColor.setFill()
+ rectPath.fill()
+ }
+
+ let path = UIBezierPath(roundedRect: rect,
+ byRoundingCorners: corners.uiRectCorner,
+ cornerRadii: CGSize(width: radius, height: radius)).cgPath
context.addPath(path)
context.clip()
base.draw(in: rect)
@@ -449,7 +469,7 @@ extension Kingfisher where Base: Image {
/// Create an image with blur effect based on `self`.
///
- /// - parameter radius: The blur radius should be used when creating blue.
+ /// - parameter radius: The blur radius should be used when creating blur effect.
///
/// - returns: An image with blur effect applied.
///
@@ -501,7 +521,7 @@ extension Kingfisher where Base: Image {
return vImage_Buffer(data: data, height: height, width: width, rowBytes: rowBytes)
}
- guard let context = beginContext(size: size) else {
+ guard let context = beginContext(size: size, scale: scale) else {
assertionFailure("[Kingfisher] Failed to create CG context for blurring image.")
return base
}
@@ -511,7 +531,7 @@ extension Kingfisher where Base: Image {
var inBuffer = createEffectBuffer(context)
- guard let outContext = beginContext(size: size) else {
+ guard let outContext = beginContext(size: size, scale: scale) else {
assertionFailure("[Kingfisher] Failed to create CG context for blurring image.")
return base
}
@@ -560,7 +580,7 @@ extension Kingfisher where Base: Image {
base.draw(in: rect)
if fraction > 0 {
color.withAlphaComponent(1 - fraction).set()
- NSRectFillUsingOperation(rect, .sourceAtop)
+ rect.fill(using: .sourceAtop)
}
#else
color.set()
@@ -603,14 +623,14 @@ extension Kingfisher where Base: Image {
#if os(watchOS)
return base
#else
- return apply(.colorControl(brightness, contrast, saturation, inputEV))
+ return apply(.colorControl((brightness, contrast, saturation, inputEV)))
#endif
}
}
// MARK: - Decode
extension Kingfisher where Base: Image {
- var decoded: Image? {
+ var decoded: Image {
return decoded(scale: scale)
}
@@ -626,15 +646,16 @@ extension Kingfisher where Base: Image {
assertionFailure("[Kingfisher] Decoding only works for CG-based image.")
return base
}
- let colorSpace = CGColorSpaceCreateDeviceRGB()
- guard let context = beginContext(size: CGSize(width: imageRef.width, height: imageRef.height)) else {
+
+ // Draw CGImage in a plain context with scale of 1.0.
+ guard let context = beginContext(size: CGSize(width: imageRef.width, height: imageRef.height), scale: 1.0) else {
assertionFailure("[Kingfisher] Decoding fails to create a valid context.")
return base
}
defer { endContext() }
- let rect = CGRect(x: 0, y: 0, width: imageRef.width, height: imageRef.height)
+ let rect = CGRect(x: 0, y: 0, width: CGFloat(imageRef.width), height: CGFloat(imageRef.height))
context.draw(imageRef, in: rect)
let decompressedImageRef = context.makeImage()
return Kingfisher.image(cgImage: decompressedImageRef!, scale: scale, refImage: base)
@@ -762,7 +783,7 @@ extension Comparable {
extension Kingfisher where Base: Image {
- func beginContext(size: CGSize) -> CGContext? {
+ func beginContext(size: CGSize, scale: CGFloat) -> CGContext? {
#if os(macOS)
guard let rep = NSBitmapImageRep(
bitmapDataPlanes: nil,
@@ -772,7 +793,7 @@ extension Kingfisher where Base: Image {
samplesPerPixel: 4,
hasAlpha: true,
isPlanar: false,
- colorSpaceName: NSCalibratedRGBColorSpace,
+ colorSpaceName: .calibratedRGB,
bytesPerRow: 0,
bitsPerPixel: 0) else
{
@@ -786,7 +807,7 @@ extension Kingfisher where Base: Image {
return nil
}
- NSGraphicsContext.setCurrent(context)
+ NSGraphicsContext.current = context
return context.cgContext
#else
UIGraphicsBeginImageContextWithOptions(size, false, scale)
@@ -815,7 +836,7 @@ extension Kingfisher where Base: Image {
samplesPerPixel: 4,
hasAlpha: true,
isPlanar: false,
- colorSpaceName: NSCalibratedRGBColorSpace,
+ colorSpaceName: .calibratedRGB,
bytesPerRow: 0,
bitsPerPixel: 0) else
{
@@ -827,7 +848,7 @@ extension Kingfisher where Base: Image {
NSGraphicsContext.saveGraphicsState()
let context = NSGraphicsContext(bitmapImageRep: rep)
- NSGraphicsContext.setCurrent(context)
+ NSGraphicsContext.current = context
draw()
NSGraphicsContext.restoreGraphicsState()
@@ -863,120 +884,60 @@ extension Float {
}
}
-// MARK: - Deprecated. Only for back compatibility.
-extension Image {
- /**
- Normalize the image. This method does nothing in OS X.
-
- - returns: The image itself.
- */
- @available(*, deprecated,
- message: "Extensions directly on Image are deprecated. Use `kf.normalized` instead.",
- renamed: "kf.normalized")
- public func kf_normalized() -> Image {
- return kf.normalized
- }
-
- // MARK: - Round Corner
-
- /// Create a round corner image based on `self`.
- ///
- /// - parameter radius: The round corner radius of creating image.
- /// - parameter size: The target size of creating image.
- /// - parameter scale: The image scale of creating image.
- ///
- /// - returns: An image with round corner of `self`.
- ///
- /// - Note: This method only works for CG-based image.
- @available(*, deprecated,
- message: "Extensions directly on Image are deprecated. Use `kf.image(withRoundRadius:fit:scale:)` instead.",
- renamed: "kf.image")
- public func kf_image(withRoundRadius radius: CGFloat, fit size: CGSize, scale: CGFloat) -> Image {
- return kf.image(withRoundRadius: radius, fit: size)
- }
-
- // MARK: - Resize
- /// Resize `self` to an image of new size.
- ///
- /// - parameter size: The target size.
- ///
- /// - returns: An image with new size.
- ///
- /// - Note: This method only works for CG-based image.
- @available(*, deprecated,
- message: "Extensions directly on Image are deprecated. Use `kf.resize(to:)` instead.",
- renamed: "kf.resize")
- public func kf_resize(to size: CGSize) -> Image {
- return kf.resize(to: size)
- }
-
- // MARK: - Blur
- /// Create an image with blur effect based on `self`.
- ///
- /// - parameter radius: The blur radius should be used when creating blue.
- ///
- /// - returns: An image with blur effect applied.
- ///
- /// - Note: This method only works for CG-based image.
- @available(*, deprecated,
- message: "Extensions directly on Image are deprecated. Use `kf.blurred(withRadius:)` instead.",
- renamed: "kf.blurred")
- public func kf_blurred(withRadius radius: CGFloat) -> Image {
- return kf.blurred(withRadius: radius)
- }
-
- // MARK: - Overlay
- /// Create an image from `self` with a color overlay layer.
- ///
- /// - parameter color: The color should be use to overlay.
- /// - parameter fraction: Fraction of input color. From 0.0 to 1.0. 0.0 means solid color, 1.0 means transparent overlay.
- ///
- /// - returns: An image with a color overlay applied.
- ///
- /// - Note: This method only works for CG-based image.
- @available(*, deprecated,
- message: "Extensions directly on Image are deprecated. Use `kf.overlaying(with:fraction:)` instead.",
- renamed: "kf.overlaying")
- public func kf_overlaying(with color: Color, fraction: CGFloat) -> Image {
- return kf.overlaying(with: color, fraction: fraction)
- }
-
- // MARK: - Tint
-
- /// Create an image from `self` with a color tint.
- ///
- /// - parameter color: The color should be used to tint `self`
- ///
- /// - returns: An image with a color tint applied.
- @available(*, deprecated,
- message: "Extensions directly on Image are deprecated. Use `kf.tinted(with:)` instead.",
- renamed: "kf.tinted")
- public func kf_tinted(with color: Color) -> Image {
- return kf.tinted(with: color)
+#if os(macOS)
+extension NSBezierPath {
+ convenience init(roundedRect rect: NSRect, topLeftRadius: CGFloat, topRightRadius: CGFloat,
+ bottomLeftRadius: CGFloat, bottomRightRadius: CGFloat)
+ {
+ self.init()
+
+ let maxCorner = min(rect.width, rect.height) / 2
+
+ let radiusTopLeft = min(maxCorner, max(0, topLeftRadius))
+ let radiustopRight = min(maxCorner, max(0, topRightRadius))
+ let radiusbottomLeft = min(maxCorner, max(0, bottomLeftRadius))
+ let radiusbottomRight = min(maxCorner, max(0, bottomRightRadius))
+
+ guard !NSIsEmptyRect(rect) else {
+ return
+ }
+
+ let topLeft = NSMakePoint(NSMinX(rect), NSMaxY(rect));
+ let topRight = NSMakePoint(NSMaxX(rect), NSMaxY(rect));
+ let bottomRight = NSMakePoint(NSMaxX(rect), NSMinY(rect));
+
+ move(to: NSMakePoint(NSMidX(rect), NSMaxY(rect)))
+ appendArc(from: topLeft, to: rect.origin, radius: radiusTopLeft)
+ appendArc(from: rect.origin, to: bottomRight, radius: radiusbottomLeft)
+ appendArc(from: bottomRight, to: topRight, radius: radiusbottomRight)
+ appendArc(from: topRight, to: topLeft, radius: radiustopRight)
+ close()
+ }
+
+ convenience init(roundedRect rect: NSRect, byRoundingCorners corners: RectCorner, radius: CGFloat) {
+ let radiusTopLeft = corners.contains(.topLeft) ? radius : 0
+ let radiusTopRight = corners.contains(.topRight) ? radius : 0
+ let radiusBottomLeft = corners.contains(.bottomLeft) ? radius : 0
+ let radiusBottomRight = corners.contains(.bottomRight) ? radius : 0
+
+ self.init(roundedRect: rect, topLeftRadius: radiusTopLeft, topRightRadius: radiusTopRight,
+ bottomLeftRadius: radiusBottomLeft, bottomRightRadius: radiusBottomRight)
}
+}
- // MARK: - Color Control
-
- /// Create an image from `self` with color control.
- ///
- /// - parameter brightness: Brightness changing to image.
- /// - parameter contrast: Contrast changing to image.
- /// - parameter saturation: Saturation changing to image.
- /// - parameter inputEV: InputEV changing to image.
- ///
- /// - returns: An image with color control applied.
- @available(*, deprecated,
- message: "Extensions directly on Image are deprecated. Use `kf.adjusted` instead.",
- renamed: "kf.adjusted")
- public func kf_adjusted(brightness: CGFloat, contrast: CGFloat, saturation: CGFloat, inputEV: CGFloat) -> Image {
- return kf.adjusted(brightness: brightness, contrast: contrast, saturation: saturation, inputEV: inputEV)
+#else
+extension RectCorner {
+ var uiRectCorner: UIRectCorner {
+
+ var result: UIRectCorner = []
+
+ if self.contains(.topLeft) { result.insert(.topLeft) }
+ if self.contains(.topRight) { result.insert(.topRight) }
+ if self.contains(.bottomLeft) { result.insert(.bottomLeft) }
+ if self.contains(.bottomRight) { result.insert(.bottomRight) }
+
+ return result
}
}
+#endif
-extension Kingfisher where Base: Image {
- @available(*, deprecated,
- message: "`scale` is not used. Use the version without scale instead. (Remove the `scale` argument)")
- public func image(withRoundRadius radius: CGFloat, fit size: CGSize, scale: CGFloat) -> Image {
- return image(withRoundRadius: radius, fit: size)
- }
-}
diff --git a/WRNavigationBar_swift/Pods/Kingfisher/Sources/ImageCache.swift b/WRNavigationBar_swift/Pods/Kingfisher/Sources/ImageCache.swift
index 62aaa0b..8d445b5 100755
--- a/WRNavigationBar_swift/Pods/Kingfisher/Sources/ImageCache.swift
+++ b/WRNavigationBar_swift/Pods/Kingfisher/Sources/ImageCache.swift
@@ -60,6 +60,13 @@ Cache type of a cached image.
*/
public enum CacheType {
case none, memory, disk
+
+ public var cached: Bool {
+ switch self {
+ case .memory, .disk: return true
+ case .none: return false
+ }
+ }
}
/// `ImageCache` represents both the memory and disk cache system of Kingfisher.
@@ -288,6 +295,10 @@ open class ImageCache {
options.callbackDispatchQueue.safeAsync {
completionHandler(image, .memory)
}
+ } else if options.fromMemoryCacheOrRefresh { // Only allows to get images from memory cache.
+ options.callbackDispatchQueue.safeAsync {
+ completionHandler(nil, .none)
+ }
} else {
var sSelf: ImageCache! = self
block = DispatchWorkItem(block: {
@@ -295,7 +306,7 @@ open class ImageCache {
if let image = sSelf.retrieveImageInDiskCache(forKey: key, options: options) {
if options.backgroundDecode {
sSelf.processQueue.async {
- let result = image.kf.decoded(scale: options.scaleFactor)
+ let result = image.kf.decoded
sSelf.store(result,
forKey: key,
@@ -303,7 +314,6 @@ open class ImageCache {
cacheSerializer: options.cacheSerializer,
toDisk: false,
completionHandler: nil)
-
options.callbackDispatchQueue.safeAsync {
completionHandler(result, .memory)
sSelf = nil
@@ -542,27 +552,17 @@ open class ImageCache {
// MARK: - Check cache status
- /**
- * Cache result for checking whether an image is cached for a key.
- */
- public struct CacheCheckResult {
- public let cached: Bool
- public let cacheType: CacheType?
- }
-
- /**
- Check whether an image is cached for a key.
-
- - parameter key: Key for the image.
-
- - returns: The check result.
- */
- open func isImageCached(forKey key: String, processorIdentifier identifier: String = "") -> CacheCheckResult {
-
+ /// Cache type for checking whether an image is cached for a key in current cache.
+ ///
+ /// - Parameters:
+ /// - key: Key for the image.
+ /// - identifier: Processor identifier which used for this image. Default is empty string.
+ /// - Returns: A `CacheType` instance which indicates the cache status. `.none` means the image is not in cache yet.
+ open func imageCachedType(forKey key: String, processorIdentifier identifier: String = "") -> CacheType {
let computedKey = key.computedKey(with: identifier)
if memoryCache.object(forKey: computedKey as NSString) != nil {
- return CacheCheckResult(cached: true, cacheType: .memory)
+ return .memory
}
let filePath = cachePath(forComputedKey: computedKey)
@@ -571,12 +571,12 @@ open class ImageCache {
ioQueue.sync {
diskCached = fileManager.fileExists(atPath: filePath)
}
-
+
if diskCached {
- return CacheCheckResult(cached: true, cacheType: .disk)
+ return .disk
}
- return CacheCheckResult(cached: false, cacheType: nil)
+ return .none
}
/**
@@ -652,6 +652,39 @@ extension ImageCache {
}
}
+// MARK: - Deprecated
+extension ImageCache {
+ /**
+ * Cache result for checking whether an image is cached for a key.
+ */
+ @available(*, deprecated,
+ message: "CacheCheckResult is deprecated. Use imageCachedType(forKey:processorIdentifier:) API instead.")
+ public struct CacheCheckResult {
+ public let cached: Bool
+ public let cacheType: CacheType?
+ }
+
+ /**
+ Check whether an image is cached for a key.
+
+ - parameter key: Key for the image.
+
+ - returns: The check result.
+ */
+ @available(*, deprecated,
+ message: "Use imageCachedType(forKey:processorIdentifier:) instead. CacheCheckResult.none indicates not being cached.",
+ renamed: "imageCachedType(forKey:processorIdentifier:)")
+ open func isImageCached(forKey key: String, processorIdentifier identifier: String = "") -> CacheCheckResult {
+ let result = imageCachedType(forKey: key, processorIdentifier: identifier)
+ switch result {
+ case .memory, .disk:
+ return CacheCheckResult(cached: true, cacheType: result)
+ case .none:
+ return CacheCheckResult(cached: false, cacheType: nil)
+ }
+ }
+}
+
extension Kingfisher where Base: Image {
var imageCost: Int {
return images == nil ?
diff --git a/WRNavigationBar_swift/Pods/Kingfisher/Sources/ImageDownloader.swift b/WRNavigationBar_swift/Pods/Kingfisher/Sources/ImageDownloader.swift
index 46039b4..e318d59 100755
--- a/WRNavigationBar_swift/Pods/Kingfisher/Sources/ImageDownloader.swift
+++ b/WRNavigationBar_swift/Pods/Kingfisher/Sources/ImageDownloader.swift
@@ -108,6 +108,14 @@ public protocol ImageDownloaderDelegate: class {
*/
func imageDownloader(_ downloader: ImageDownloader, didDownload image: Image, for url: URL, with response: URLResponse?)
+ /**
+ Called when the `ImageDownloader` object starts to download an image from specified URL.
+
+ - parameter downloader: The `ImageDownloader` object starts the downloading.
+ - parameter url: URL of the original request.
+ - parameter response: The request object of the downloading process.
+ */
+ func imageDownloader(_ downloader: ImageDownloader, willDownloadImageForURL url: URL, with request: URLRequest?)
/**
Check if a received HTTP status code is valid or not.
@@ -124,14 +132,32 @@ public protocol ImageDownloaderDelegate: class {
you can implement this method to change that behavior.
*/
func isValidStatusCode(_ code: Int, for downloader: ImageDownloader) -> Bool
+
+ /**
+ Called when the `ImageDownloader` object successfully downloaded image data from specified URL.
+
+ - parameter downloader: The `ImageDownloader` object finishes data downloading.
+ - parameter data: Downloaded data.
+ - parameter url: URL of the original request URL.
+
+ - returns: The data from which Kingfisher should use to create an image.
+
+ - Note: This callback can be used to preprocess raw image data
+ before creation of UIImage instance (i.e. decrypting or verification).
+ */
+ func imageDownloader(_ downloader: ImageDownloader, didDownload data: Data, for url: URL) -> Data?
}
extension ImageDownloaderDelegate {
public func imageDownloader(_ downloader: ImageDownloader, didDownload image: Image, for url: URL, with response: URLResponse?) {}
+ public func imageDownloader(_ downloader: ImageDownloader, willDownloadImageForURL url: URL, with request: URLRequest?) {}
public func isValidStatusCode(_ code: Int, for downloader: ImageDownloader) -> Bool {
return (200..<400).contains(code)
}
+ public func imageDownloader(_ downloader: ImageDownloader, didDownload data: Data, for url: URL) -> Data? {
+ return data
+ }
}
/// Protocol indicates that an authentication challenge could be handled.
@@ -144,9 +170,22 @@ public protocol AuthenticationChallengeResponsable: class {
- parameter challenge: An object that contains the request for authentication.
- parameter completionHandler: A handler that your delegate method must call.
- - Note: This method is a forward from `URLSession(:didReceiveChallenge:completionHandler:)`. Please refer to the document of it in `NSURLSessionDelegate`.
+ - Note: This method is a forward from `URLSessionDelegate.urlSession(:didReceiveChallenge:completionHandler:)`. Please refer to the document of it in `URLSessionDelegate`.
*/
func downloader(_ downloader: ImageDownloader, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void)
+
+ /**
+ Called when an session level authentication challenge is received.
+ This method provide a chance to handle and response to the authentication challenge before downloading could start.
+
+ - parameter downloader: The downloader which receives this challenge.
+ - parameter task: The task whose request requires authentication.
+ - parameter challenge: An object that contains the request for authentication.
+ - parameter completionHandler: A handler that your delegate method must call.
+
+ - Note: This method is a forward from `URLSessionTaskDelegate.urlSession(:task:didReceiveChallenge:completionHandler:)`. Please refer to the document of it in `URLSessionTaskDelegate`.
+ */
+ func downloader(_ downloader: ImageDownloader, task: URLSessionTask, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void)
}
extension AuthenticationChallengeResponsable {
@@ -163,6 +202,12 @@ extension AuthenticationChallengeResponsable {
completionHandler(.performDefaultHandling, nil)
}
+
+ func downloader(_ downloader: ImageDownloader, task: URLSessionTask, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) {
+
+ completionHandler(.performDefaultHandling, nil)
+ }
+
}
/// `ImageDownloader` represents a downloading manager for requesting the image with a URL from server.
@@ -174,6 +219,7 @@ open class ImageDownloader {
var downloadTaskCount = 0
var downloadTask: RetrieveImageDownloadTask?
+ var cancelSemaphore: DispatchSemaphore?
}
// MARK: - Public property
@@ -189,12 +235,13 @@ open class ImageDownloader {
/// You could change the configuration before a downloaing task starts. A configuration without persistent storage for caches is requsted for downloader working correctly.
open var sessionConfiguration = URLSessionConfiguration.ephemeral {
didSet {
+ session?.invalidateAndCancel()
session = URLSession(configuration: sessionConfiguration, delegate: sessionHandler, delegateQueue: OperationQueue.main)
}
}
/// Whether the download requests should use pipeling or not. Default is false.
- open var requestsUsePipeling = false
+ open var requestsUsePipelining = false
fileprivate let sessionHandler: ImageDownloaderSessionHandler
fileprivate var session: URLSession?
@@ -209,6 +256,7 @@ open class ImageDownloader {
// MARK: - Internal property
let barrierQueue: DispatchQueue
let processQueue: DispatchQueue
+ let cancelQueue: DispatchQueue
typealias CallbackPair = (progressBlock: ImageDownloaderProgressBlock?, completionHandler: ImageDownloaderCompletionHandler?)
@@ -232,6 +280,7 @@ open class ImageDownloader {
barrierQueue = DispatchQueue(label: "com.onevcat.Kingfisher.ImageDownloader.Barrier.\(name)", attributes: .concurrent)
processQueue = DispatchQueue(label: "com.onevcat.Kingfisher.ImageDownloader.Process.\(name)", attributes: .concurrent)
+ cancelQueue = DispatchQueue(label: "com.onevcat.Kingfisher.ImageDownloader.Cancel.\(name)")
sessionHandler = ImageDownloaderSessionHandler()
@@ -240,9 +289,13 @@ open class ImageDownloader {
session = URLSession(configuration: sessionConfiguration, delegate: sessionHandler, delegateQueue: .main)
}
+ deinit {
+ session?.invalidateAndCancel()
+ }
+
func fetchLoad(for url: URL) -> ImageFetchLoad? {
var fetchLoad: ImageFetchLoad?
- barrierQueue.sync { fetchLoad = fetchLoads[url] }
+ barrierQueue.sync(flags: .barrier) { fetchLoad = fetchLoads[url] }
return fetchLoad
}
@@ -250,6 +303,7 @@ open class ImageDownloader {
Download an image with a URL and option.
- parameter url: Target URL.
+ - parameter retrieveImageTask: The task to cooporate with cache. Pass `nil` if you are not trying to use downloader and cache.
- parameter options: The options could control download behavior. See `KingfisherOptionsInfo`.
- parameter progressBlock: Called when the download progress updated.
- parameter completionHandler: Called when the download progress finishes.
@@ -258,25 +312,10 @@ open class ImageDownloader {
*/
@discardableResult
open func downloadImage(with url: URL,
- options: KingfisherOptionsInfo? = nil,
- progressBlock: ImageDownloaderProgressBlock? = nil,
- completionHandler: ImageDownloaderCompletionHandler? = nil) -> RetrieveImageDownloadTask?
- {
- return downloadImage(with: url,
- retrieveImageTask: nil,
- options: options,
- progressBlock: progressBlock,
- completionHandler: completionHandler)
- }
-}
-
-// MARK: - Download method
-extension ImageDownloader {
- func downloadImage(with url: URL,
- retrieveImageTask: RetrieveImageTask?,
- options: KingfisherOptionsInfo?,
- progressBlock: ImageDownloaderProgressBlock?,
- completionHandler: ImageDownloaderCompletionHandler?) -> RetrieveImageDownloadTask?
+ retrieveImageTask: RetrieveImageTask? = nil,
+ options: KingfisherOptionsInfo? = nil,
+ progressBlock: ImageDownloaderProgressBlock? = nil,
+ completionHandler: ImageDownloaderCompletionHandler? = nil) -> RetrieveImageDownloadTask?
{
if let retrieveImageTask = retrieveImageTask, retrieveImageTask.cancelledBeforeDownloadStarting {
completionHandler?(nil, NSError(domain: KingfisherErrorDomain, code: KingfisherError.downloadCancelledBeforeStarting.rawValue, userInfo: nil), nil, nil)
@@ -287,7 +326,7 @@ extension ImageDownloader {
// We need to set the URL as the load key. So before setup progress, we need to ask the `requestModifier` for a final URL.
var request = URLRequest(url: url, cachePolicy: .reloadIgnoringLocalCacheData, timeoutInterval: timeout)
- request.httpShouldUsePipelining = requestsUsePipeling
+ request.httpShouldUsePipelining = requestsUsePipelining
if let modifier = options?.modifier {
guard let r = modifier.modified(for: request) else {
@@ -309,9 +348,10 @@ extension ImageDownloader {
let dataTask = session.dataTask(with: request)
fetchLoad.downloadTask = RetrieveImageDownloadTask(internalTask: dataTask, ownerDownloader: self)
-
+
dataTask.priority = options?.downloadPriority ?? URLSessionTask.defaultPriority
dataTask.resume()
+ self.delegate?.imageDownloader(self, willDownloadImageForURL: url, with: request)
// Hold self while the task is executing.
self.sessionHandler.downloadHolder = self
@@ -325,25 +365,45 @@ extension ImageDownloader {
return downloadTask
}
+}
+
+// MARK: - Download method
+extension ImageDownloader {
+
// A single key may have multiple callbacks. Only download once.
- func setup(progressBlock: ImageDownloaderProgressBlock?, with completionHandler: ImageDownloaderCompletionHandler?, for url: URL, options: KingfisherOptionsInfo?, started: ((URLSession, ImageFetchLoad) -> Void)) {
+ func setup(progressBlock: ImageDownloaderProgressBlock?, with completionHandler: ImageDownloaderCompletionHandler?, for url: URL, options: KingfisherOptionsInfo?, started: @escaping ((URLSession, ImageFetchLoad) -> Void)) {
- barrierQueue.sync(flags: .barrier) {
- let loadObjectForURL = fetchLoads[url] ?? ImageFetchLoad()
- let callbackPair = (progressBlock: progressBlock, completionHandler: completionHandler)
-
- loadObjectForURL.contents.append((callbackPair, options ?? KingfisherEmptyOptionsInfo))
-
- fetchLoads[url] = loadObjectForURL
-
- if let session = session {
- started(session, loadObjectForURL)
+ func prepareFetchLoad() {
+ barrierQueue.sync(flags: .barrier) {
+ let loadObjectForURL = fetchLoads[url] ?? ImageFetchLoad()
+ let callbackPair = (progressBlock: progressBlock, completionHandler: completionHandler)
+
+ loadObjectForURL.contents.append((callbackPair, options ?? KingfisherEmptyOptionsInfo))
+
+ fetchLoads[url] = loadObjectForURL
+
+ if let session = session {
+ started(session, loadObjectForURL)
+ }
}
}
+
+ if let fetchLoad = fetchLoad(for: url), fetchLoad.downloadTaskCount == 0 {
+ if fetchLoad.cancelSemaphore == nil {
+ fetchLoad.cancelSemaphore = DispatchSemaphore(value: 0)
+ }
+ cancelQueue.async {
+ _ = fetchLoad.cancelSemaphore?.wait(timeout: .distantFuture)
+ fetchLoad.cancelSemaphore = nil
+ prepareFetchLoad()
+ }
+ } else {
+ prepareFetchLoad()
+ }
}
func cancelDownloadingTask(_ task: RetrieveImageDownloadTask) {
- barrierQueue.sync {
+ barrierQueue.sync(flags: .barrier) {
if let URL = task.internalTask.originalRequest?.url, let imageFetchLoad = self.fetchLoads[URL] {
imageFetchLoad.downloadTaskCount -= 1
if imageFetchLoad.downloadTaskCount == 0 {
@@ -352,13 +412,6 @@ extension ImageDownloader {
}
}
}
-
- func clean(for url: URL) {
- barrierQueue.sync(flags: .barrier) {
- fetchLoads.removeValue(forKey: url)
- return
- }
- }
}
// MARK: - NSURLSessionDataDelegate
@@ -438,15 +491,24 @@ class ImageDownloaderSessionHandler: NSObject, URLSessionDataDelegate, Authentic
downloader.authenticationChallengeResponder?.downloader(downloader, didReceive: challenge, completionHandler: completionHandler)
}
- private func cleanFetchLoad(for url: URL) {
+ func urlSession(_ session: URLSession, task: URLSessionTask, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) {
guard let downloader = downloadHolder else {
return
}
- downloader.clean(for: url)
-
- if downloader.fetchLoads.isEmpty {
- downloadHolder = nil
+ downloader.authenticationChallengeResponder?.downloader(downloader, task: task, didReceive: challenge, completionHandler: completionHandler)
+ }
+
+ private func cleanFetchLoad(for url: URL) {
+ guard let downloader = downloadHolder else {
+ return
+ }
+
+ downloader.barrierQueue.sync(flags: .barrier) {
+ downloader.fetchLoads.removeValue(forKey: url)
+ if downloader.fetchLoads.isEmpty {
+ downloadHolder = nil
+ }
}
}
@@ -458,6 +520,11 @@ class ImageDownloaderSessionHandler: NSObject, URLSessionDataDelegate, Authentic
// We need to clean the fetch load first, before actually calling completion handler.
cleanFetchLoad(for: url)
+ var leftSignal: Int
+ repeat {
+ leftSignal = fetchLoad.cancelSemaphore?.signal() ?? 0
+ } while leftSignal != 0
+
for content in fetchLoad.contents {
content.options.callbackDispatchQueue.safeAsync {
content.callback.completionHandler?(nil, error as NSError, url, nil)
@@ -480,7 +547,14 @@ class ImageDownloaderSessionHandler: NSObject, URLSessionDataDelegate, Authentic
self.cleanFetchLoad(for: url)
- let data = fetchLoad.responseData as Data
+ let data: Data?
+ let fetchedData = fetchLoad.responseData as Data
+
+ if let delegate = downloader.delegate {
+ data = delegate.imageDownloader(downloader, didDownload: fetchedData, for: url)
+ } else {
+ data = fetchedData
+ }
// Cache the processed images. So we do not need to re-process the image if using the same processor.
// Key is the identifier of processor.
@@ -494,9 +568,8 @@ class ImageDownloaderSessionHandler: NSObject, URLSessionDataDelegate, Authentic
let processor = options.processor
var image = imageCache[processor.identifier]
- if image == nil {
+ if let data = data, image == nil {
image = processor.process(item: .data(data), options: options)
-
// Add the processed image to cache.
// If `image` is nil, nothing will happen (since the key is not existing before).
imageCache[processor.identifier] = image
@@ -507,7 +580,7 @@ class ImageDownloaderSessionHandler: NSObject, URLSessionDataDelegate, Authentic
downloader.delegate?.imageDownloader(downloader, didDownload: image, for: url, with: task.response)
if options.backgroundDecode {
- let decodedImage = image.kf.decoded(scale: options.scaleFactor)
+ let decodedImage = image.kf.decoded
callbackQueue.safeAsync { completionHandler?(decodedImage, nil, url, data) }
} else {
callbackQueue.safeAsync { completionHandler?(image, nil, url, data) }
@@ -530,3 +603,4 @@ class ImageDownloaderSessionHandler: NSObject, URLSessionDataDelegate, Authentic
// Placeholder. For retrieving extension methods of ImageDownloaderDelegate
extension ImageDownloader: ImageDownloaderDelegate {}
+
diff --git a/WRNavigationBar_swift/Pods/Kingfisher/Sources/ImagePrefetcher.swift b/WRNavigationBar_swift/Pods/Kingfisher/Sources/ImagePrefetcher.swift
index b7c0a21..558ddfa 100755
--- a/WRNavigationBar_swift/Pods/Kingfisher/Sources/ImagePrefetcher.swift
+++ b/WRNavigationBar_swift/Pods/Kingfisher/Sources/ImagePrefetcher.swift
@@ -181,13 +181,9 @@ public class ImagePrefetcher {
*/
public func stop() {
DispatchQueue.main.safeAsync {
-
if self.finished { return }
-
self.stopped = true
- self.tasks.forEach { (_, task) -> () in
- task.cancel()
- }
+ self.tasks.values.forEach { $0.cancel() }
}
}
@@ -237,9 +233,8 @@ public class ImagePrefetcher {
if optionsInfo.forceRefresh {
downloadAndCache(resource)
} else {
- let alreadyInCache = manager.cache.isImageCached(forKey: resource.cacheKey,
+ let alreadyInCache = manager.cache.imageCachedType(forKey: resource.cacheKey,
processorIdentifier: optionsInfo.processor.identifier).cached
-
if alreadyInCache {
append(cached: resource)
} else {
diff --git a/WRNavigationBar_swift/Pods/Kingfisher/Sources/ImageProcessor.swift b/WRNavigationBar_swift/Pods/Kingfisher/Sources/ImageProcessor.swift
index dc9088f..e448802 100644
--- a/WRNavigationBar_swift/Pods/Kingfisher/Sources/ImageProcessor.swift
+++ b/WRNavigationBar_swift/Pods/Kingfisher/Sources/ImageProcessor.swift
@@ -27,7 +27,6 @@
import Foundation
import CoreGraphics
-
/// The item which could be processed by an `ImageProcessor`
///
/// - image: Input image
@@ -88,6 +87,14 @@ public extension ImageProcessor {
}
}
+func ==(left: ImageProcessor, right: ImageProcessor) -> Bool {
+ return left.identifier == right.identifier
+}
+
+func !=(left: ImageProcessor, right: ImageProcessor) -> Bool {
+ return !(left == right)
+}
+
fileprivate struct GeneralProcessor: ImageProcessor {
let identifier: String
let p: ProcessorImp
@@ -127,12 +134,32 @@ public struct DefaultImageProcessor: ImageProcessor {
return Kingfisher.image(
data: data,
scale: options.scaleFactor,
- preloadAllGIFData: options.preloadAllGIFData,
+ preloadAllAnimationData: options.preloadAllAnimationData,
onlyFirstFrame: options.onlyLoadFirstFrame)
}
}
}
+public struct RectCorner: OptionSet {
+ public let rawValue: Int
+ public static let topLeft = RectCorner(rawValue: 1 << 0)
+ public static let topRight = RectCorner(rawValue: 1 << 1)
+ public static let bottomLeft = RectCorner(rawValue: 1 << 2)
+ public static let bottomRight = RectCorner(rawValue: 1 << 3)
+ public static let all: RectCorner = [.topLeft, .topRight, .bottomLeft, .bottomRight]
+
+ public init(rawValue: Int) {
+ self.rawValue = rawValue
+ }
+
+ var cornerIdentifier: String {
+ if self == .all {
+ return ""
+ }
+ return "_corner(\(rawValue))"
+ }
+}
+
/// Processor for making round corner images. Only CG-based images are supported in macOS,
/// if a non-CG image passed in, the processor will do nothing.
public struct RoundCornerImageProcessor: ImageProcessor {
@@ -144,23 +171,43 @@ public struct RoundCornerImageProcessor: ImageProcessor {
/// Corner radius will be applied in processing.
public let cornerRadius: CGFloat
+ /// The target corners which will be applied rounding.
+ public let roundingCorners: RectCorner
+
/// Target size of output image should be. If `nil`, the image will keep its original size after processing.
public let targetSize: CGSize?
-
+
+ /// Background color of the output image. If `nil`, it will stay transparent.
+ public let backgroundColor: Color?
+
/// Initialize a `RoundCornerImageProcessor`
///
- /// - parameter cornerRadius: Corner radius will be applied in processing.
- /// - parameter targetSize: Target size of output image should be. If `nil`,
- /// the image will keep its original size after processing.
- /// Default is `nil`.
- public init(cornerRadius: CGFloat, targetSize: CGSize? = nil) {
+ /// - parameter cornerRadius: Corner radius will be applied in processing.
+ /// - parameter targetSize: Target size of output image should be. If `nil`,
+ /// the image will keep its original size after processing.
+ /// Default is `nil`.
+ /// - parameter corners: The target corners which will be applied rounding. Default is `.all`.
+ /// - parameter backgroundColor: Backgroud color to apply for the output image. Default is `nil`.
+ public init(cornerRadius: CGFloat, targetSize: CGSize? = nil, roundingCorners corners: RectCorner = .all, backgroundColor: Color? = nil) {
self.cornerRadius = cornerRadius
self.targetSize = targetSize
- if let size = targetSize {
- self.identifier = "com.onevcat.Kingfisher.RoundCornerImageProcessor(\(cornerRadius)_\(size))"
- } else {
- self.identifier = "com.onevcat.Kingfisher.RoundCornerImageProcessor(\(cornerRadius))"
- }
+ self.roundingCorners = corners
+ self.backgroundColor = backgroundColor
+
+ self.identifier = {
+ var identifier = ""
+
+ if let size = targetSize {
+ identifier = "com.onevcat.Kingfisher.RoundCornerImageProcessor(\(cornerRadius)_\(size)\(corners.cornerIdentifier))"
+ } else {
+ identifier = "com.onevcat.Kingfisher.RoundCornerImageProcessor(\(cornerRadius)\(corners.cornerIdentifier))"
+ }
+ if let backgroundColor = backgroundColor {
+ identifier += "_\(backgroundColor)"
+ }
+
+ return identifier
+ }()
}
/// Process an input `ImageProcessItem` item to an image for this processor.
@@ -175,7 +222,7 @@ public struct RoundCornerImageProcessor: ImageProcessor {
switch item {
case .image(let image):
let size = targetSize ?? image.kf.size
- return image.kf.image(withRoundRadius: cornerRadius, fit: size)
+ return image.kf.image(withRoundRadius: cornerRadius, fit: size, roundingCorners: roundingCorners, backgroundColor: backgroundColor)
case .data(_):
return (DefaultImageProcessor.default >> self).process(item: item, options: options)
}
@@ -537,25 +584,3 @@ fileprivate extension Color {
return String(format:"#%08x", rgba)
}
}
-
-// MARK: - Deprecated
-extension ResizingImageProcessor {
- /// Reference size of output image should follow.
- @available(*, deprecated,
- message: "targetSize are renamed. Use `referenceSize` instead",
- renamed: "referenceSize")
- public var targetSize: CGSize {
- return referenceSize
- }
-
- /// Initialize a `ResizingImageProcessor`
- ///
- /// - parameter targetSize: Reference size of output image should follow.
- /// - parameter contentMode: Target content mode of output image should be.
- @available(*, deprecated,
- message: "targetSize and contentMode are renamed. Use `init(referenceSize:mode:)` instead",
- renamed: "init(referenceSize:mode:)")
- public init(targetSize: CGSize, contentMode: ContentMode = .none) {
- self.init(referenceSize: targetSize, mode: contentMode)
- }
-}
diff --git a/WRNavigationBar_swift/Pods/Kingfisher/Sources/ImageView+Kingfisher.swift b/WRNavigationBar_swift/Pods/Kingfisher/Sources/ImageView+Kingfisher.swift
index ac92a4f..b39bfae 100755
--- a/WRNavigationBar_swift/Pods/Kingfisher/Sources/ImageView+Kingfisher.swift
+++ b/WRNavigationBar_swift/Pods/Kingfisher/Sources/ImageView+Kingfisher.swift
@@ -33,7 +33,7 @@ import UIKit
// MARK: - Extension methods.
/**
- * Set image to use from web.
+ * Set image to use from web.
*/
extension Kingfisher where Base: ImageView {
/**
@@ -49,25 +49,29 @@ extension Kingfisher where Base: ImageView {
- note: Both the `progressBlock` and `completionHandler` will be invoked in main thread.
The `CallbackDispatchQueue` specified in `optionsInfo` will not be used in callbacks of this method.
+
+ If `resource` is `nil`, the `placeholder` image will be set and
+ `completionHandler` will be called with both `error` and `image` being `nil`.
*/
@discardableResult
public func setImage(with resource: Resource?,
- placeholder: Image? = nil,
+ placeholder: Placeholder? = nil,
options: KingfisherOptionsInfo? = nil,
progressBlock: DownloadProgressBlock? = nil,
completionHandler: CompletionHandler? = nil) -> RetrieveImageTask
{
guard let resource = resource else {
- base.image = placeholder
+ self.placeholder = placeholder
setWebURL(nil)
completionHandler?(nil, nil, .none, nil)
return .empty
}
- var options = options ?? KingfisherEmptyOptionsInfo
+ var options = KingfisherManager.shared.defaultOptions + (options ?? KingfisherEmptyOptionsInfo)
+ let noImageOrPlaceholderSet = base.image == nil && self.placeholder == nil
- if !options.keepCurrentImageWhileLoading {
- base.image = placeholder
+ if !options.keepCurrentImageWhileLoading || noImageOrPlaceholderSet { // Always set placeholder while there is no image/placehoer yet.
+ self.placeholder = placeholder
}
let maybeIndicator = indicator
@@ -75,8 +79,8 @@ extension Kingfisher where Base: ImageView {
setWebURL(resource.downloadURL)
- if base.shouldPreloadAllGIF() {
- options.append(.preloadAllGIFData)
+ if base.shouldPreloadAllAnimation() {
+ options.append(.preloadAllAnimationData)
}
let task = KingfisherManager.shared.retrieveImage(
@@ -92,20 +96,22 @@ extension Kingfisher where Base: ImageView {
},
completionHandler: {[weak base] image, error, cacheType, imageURL in
DispatchQueue.main.safeAsync {
+ maybeIndicator?.stopAnimatingView()
guard let strongBase = base, imageURL == self.webURL else {
+ completionHandler?(image, error, cacheType, imageURL)
return
}
+
self.setImageTask(nil)
guard let image = image else {
- maybeIndicator?.stopAnimatingView()
completionHandler?(nil, error, cacheType, imageURL)
return
}
- guard let transitionItem = options.firstMatchIgnoringAssociatedValue(.transition(.none)),
+ guard let transitionItem = options.lastMatchIgnoringAssociatedValue(.transition(.none)),
case .transition(let transition) = transitionItem, ( options.forceTransition || cacheType == .none) else
{
- maybeIndicator?.stopAnimatingView()
+ self.placeholder = nil
strongBase.image = image
completionHandler?(image, error, cacheType, imageURL)
return
@@ -115,6 +121,8 @@ extension Kingfisher where Base: ImageView {
UIView.transition(with: strongBase, duration: 0.0, options: [],
animations: { maybeIndicator?.stopAnimatingView() },
completion: { _ in
+
+ self.placeholder = nil
UIView.transition(with: strongBase, duration: transition.duration,
options: [transition.animationOptions, .allowUserInteraction],
animations: {
@@ -148,6 +156,7 @@ extension Kingfisher where Base: ImageView {
private var lastURLKey: Void?
private var indicatorKey: Void?
private var indicatorTypeKey: Void?
+private var placeholderKey: Void?
private var imageTaskKey: Void?
extension Kingfisher where Base: ImageView {
@@ -200,7 +209,10 @@ extension Kingfisher where Base: ImageView {
// Add new
if var newIndicator = newValue {
- newIndicator.view.frame = base.frame
+ // Set default indicator frame if the view's frame not set.
+ if newIndicator.view.frame == .zero {
+ newIndicator.view.frame = base.frame
+ }
newIndicator.viewCenter = CGPoint(x: base.bounds.midX, y: base.bounds.midY)
newIndicator.view.isHidden = true
base.addSubview(newIndicator.view)
@@ -218,75 +230,29 @@ extension Kingfisher where Base: ImageView {
fileprivate func setImageTask(_ task: RetrieveImageTask?) {
objc_setAssociatedObject(base, &imageTaskKey, task, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
}
-}
-
-
-// MARK: - Deprecated. Only for back compatibility.
-/**
-* Set image to use from web. Deprecated. Use `kf` namespacing instead.
-*/
-extension ImageView {
- /**
- Set an image with a resource, a placeholder image, options, progress handler and completion handler.
-
- - parameter resource: Resource object contains information such as `cacheKey` and `downloadURL`.
- - parameter placeholder: A placeholder image when retrieving the image at URL.
- - parameter options: A dictionary could control some behaviors. See `KingfisherOptionsInfo` for more.
- - parameter progressBlock: Called when the image downloading progress gets updated.
- - parameter completionHandler: Called when the image retrieved and set.
- - returns: A task represents the retrieving process.
-
- - note: Both the `progressBlock` and `completionHandler` will be invoked in main thread.
- The `CallbackDispatchQueue` specified in `optionsInfo` will not be used in callbacks of this method.
- */
- @available(*, deprecated, message: "Extensions directly on image views are deprecated. Use `imageView.kf.setImage` instead.", renamed: "kf.setImage")
- @discardableResult
- public func kf_setImage(with resource: Resource?,
- placeholder: Image? = nil,
- options: KingfisherOptionsInfo? = nil,
- progressBlock: DownloadProgressBlock? = nil,
- completionHandler: CompletionHandler? = nil) -> RetrieveImageTask
- {
- return kf.setImage(with: resource, placeholder: placeholder, options: options, progressBlock: progressBlock, completionHandler: completionHandler)
- }
-
- /**
- Cancel the image download task bounded to the image view if it is running.
- Nothing will happen if the downloading has already finished.
- */
- @available(*, deprecated, message: "Extensions directly on image views are deprecated. Use `imageView.kf.cancelDownloadTask` instead.", renamed: "kf.cancelDownloadTask")
- public func kf_cancelDownloadTask() { kf.cancelDownloadTask() }
-
- /// Get the image URL binded to this image view.
- @available(*, deprecated, message: "Extensions directly on image views are deprecated. Use `imageView.kf.webURL` instead.", renamed: "kf.webURL")
- public var kf_webURL: URL? { return kf.webURL }
-
- /// Holds which indicator type is going to be used.
- /// Default is .none, means no indicator will be shown.
- @available(*, deprecated, message: "Extensions directly on image views are deprecated. Use `imageView.kf.indicatorType` instead.", renamed: "kf.indicatorType")
- public var kf_indicatorType: IndicatorType {
- get { return kf.indicatorType }
- set { kf.indicatorType = newValue }
- }
-
- @available(*, deprecated, message: "Extensions directly on image views are deprecated. Use `imageView.kf.indicator` instead.", renamed: "kf.indicator")
- /// Holds any type that conforms to the protocol `Indicator`.
- /// The protocol `Indicator` has a `view` property that will be shown when loading an image.
- /// It will be `nil` if `kf_indicatorType` is `.none`.
- public private(set) var kf_indicator: Indicator? {
- get { return kf.indicator }
- set { kf.indicator = newValue }
+ public fileprivate(set) var placeholder: Placeholder? {
+ get {
+ return (objc_getAssociatedObject(base, &placeholderKey) as? Box)?.value
+ }
+
+ set {
+ if let previousPlaceholder = placeholder {
+ previousPlaceholder.remove(from: base)
+ }
+
+ if let newPlaceholder = newValue {
+ newPlaceholder.add(to: base)
+ } else {
+ base.image = nil
+ }
+
+ objc_setAssociatedObject(base, &placeholderKey, Box(value: newValue), .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
+ }
}
-
- @available(*, deprecated, message: "Extensions directly on image views are deprecated.", renamed: "kf.imageTask")
- fileprivate var kf_imageTask: RetrieveImageTask? { return kf.imageTask }
- @available(*, deprecated, message: "Extensions directly on image views are deprecated.", renamed: "kf.setImageTask")
- fileprivate func kf_setImageTask(_ task: RetrieveImageTask?) { kf.setImageTask(task) }
- @available(*, deprecated, message: "Extensions directly on image views are deprecated.", renamed: "kf.setWebURL")
- fileprivate func kf_setWebURL(_ url: URL) { kf.setWebURL(url) }
}
-extension ImageView {
- func shouldPreloadAllGIF() -> Bool { return true }
+
+@objc extension ImageView {
+ func shouldPreloadAllAnimation() -> Bool { return true }
}
diff --git a/WRNavigationBar_swift/Pods/Kingfisher/Sources/Indicator.swift b/WRNavigationBar_swift/Pods/Kingfisher/Sources/Indicator.swift
index d1f55f0..5ec5f97 100644
--- a/WRNavigationBar_swift/Pods/Kingfisher/Sources/Indicator.swift
+++ b/WRNavigationBar_swift/Pods/Kingfisher/Sources/Indicator.swift
@@ -86,41 +86,49 @@ extension Indicator {
// MARK: - ActivityIndicator
// Displays a NSProgressIndicator / UIActivityIndicatorView
-struct ActivityIndicator: Indicator {
+class ActivityIndicator: Indicator {
#if os(macOS)
private let activityIndicatorView: NSProgressIndicator
#else
private let activityIndicatorView: UIActivityIndicatorView
#endif
+ private var animatingCount = 0
var view: IndicatorView {
return activityIndicatorView
}
func startAnimatingView() {
- #if os(macOS)
- activityIndicatorView.startAnimation(nil)
- #else
- activityIndicatorView.startAnimating()
- #endif
- activityIndicatorView.isHidden = false
+ animatingCount += 1
+ // Alrady animating
+ if animatingCount == 1 {
+ #if os(macOS)
+ activityIndicatorView.startAnimation(nil)
+ #else
+ activityIndicatorView.startAnimating()
+ #endif
+ activityIndicatorView.isHidden = false
+ }
}
func stopAnimatingView() {
- #if os(macOS)
- activityIndicatorView.stopAnimation(nil)
- #else
- activityIndicatorView.stopAnimating()
- #endif
- activityIndicatorView.isHidden = true
+ animatingCount = max(animatingCount - 1, 0)
+ if animatingCount == 0 {
+ #if os(macOS)
+ activityIndicatorView.stopAnimation(nil)
+ #else
+ activityIndicatorView.stopAnimating()
+ #endif
+ activityIndicatorView.isHidden = true
+ }
}
init() {
#if os(macOS)
activityIndicatorView = NSProgressIndicator(frame: CGRect(x: 0, y: 0, width: 16, height: 16))
activityIndicatorView.controlSize = .small
- activityIndicatorView.style = .spinningStyle
+ activityIndicatorView.style = .spinning
#else
#if os(tvOS)
let indicatorStyle = UIActivityIndicatorViewStyle.white
@@ -135,7 +143,7 @@ struct ActivityIndicator: Indicator {
// MARK: - ImageIndicator
// Displays an ImageView. Supports gif
-struct ImageIndicator: Indicator {
+class ImageIndicator: Indicator {
private let animatedImageIndicatorView: ImageView
var view: IndicatorView {
@@ -145,9 +153,9 @@ struct ImageIndicator: Indicator {
init?(imageData data: Data, processor: ImageProcessor = DefaultImageProcessor.default, options: KingfisherOptionsInfo = KingfisherEmptyOptionsInfo) {
var options = options
- // Use normal image view to show gif, so we need to preload all gif data.
- if !options.preloadAllGIFData {
- options.append(.preloadAllGIFData)
+ // Use normal image view to show animations, so we need to preload all animation data.
+ if !options.preloadAllAnimationData {
+ options.append(.preloadAllAnimationData)
}
guard let image = processor.process(item: .data(data), options: options) else {
@@ -156,6 +164,7 @@ struct ImageIndicator: Indicator {
animatedImageIndicatorView = ImageView()
animatedImageIndicatorView.image = image
+ animatedImageIndicatorView.frame = CGRect(x: 0, y: 0, width: image.size.width, height: image.size.height)
#if os(macOS)
// Need for gif to animate on macOS
@@ -163,7 +172,6 @@ struct ImageIndicator: Indicator {
self.animatedImageIndicatorView.canDrawSubviewsIntoLayer = true
#else
animatedImageIndicatorView.contentMode = .center
-
animatedImageIndicatorView.autoresizingMask = [.flexibleLeftMargin,
.flexibleRightMargin,
.flexibleBottomMargin,
diff --git a/WRNavigationBar_swift/Pods/Kingfisher/Sources/Kingfisher.swift b/WRNavigationBar_swift/Pods/Kingfisher/Sources/Kingfisher.swift
index 6e2d409..c97818e 100644
--- a/WRNavigationBar_swift/Pods/Kingfisher/Sources/Kingfisher.swift
+++ b/WRNavigationBar_swift/Pods/Kingfisher/Sources/Kingfisher.swift
@@ -30,16 +30,18 @@ import ImageIO
#if os(macOS)
import AppKit
public typealias Image = NSImage
+ public typealias View = NSView
public typealias Color = NSColor
public typealias ImageView = NSImageView
- typealias Button = NSButton
+ public typealias Button = NSButton
#else
import UIKit
public typealias Image = UIImage
public typealias Color = UIColor
#if !os(watchOS)
public typealias ImageView = UIImageView
- typealias Button = UIButton
+ public typealias View = UIView
+ public typealias Button = UIButton
#endif
#endif
diff --git a/WRNavigationBar_swift/Pods/Kingfisher/Sources/KingfisherManager.swift b/WRNavigationBar_swift/Pods/Kingfisher/Sources/KingfisherManager.swift
index eb29f3d..85503f5 100755
--- a/WRNavigationBar_swift/Pods/Kingfisher/Sources/KingfisherManager.swift
+++ b/WRNavigationBar_swift/Pods/Kingfisher/Sources/KingfisherManager.swift
@@ -43,11 +43,6 @@ public class RetrieveImageTask {
// the download task should not begin.
var cancelledBeforeDownloadStarting: Bool = false
- /// The disk retrieve task in this image task. Kingfisher will try to look up in cache first. This task represent the cache search task.
- @available(*, deprecated,
- message: "diskRetrieveTask is not in use anymore. You cannot cancel a disk retrieve task anymore once it started.")
- public var diskRetrieveTask: RetrieveImageDiskTask?
-
/// The network retrieve task in this image task.
public var downloadTask: RetrieveImageDownloadTask?
@@ -79,6 +74,19 @@ public class KingfisherManager {
/// Downloader used by this manager
public var downloader: ImageDownloader
+ /// Default options used by the manager. This option will be used in
+ /// Kingfisher manager related methods, including all image view and
+ /// button extension methods. You can also passing the options per image by
+ /// sending an `options` parameter to Kingfisher's APIs, the per image option
+ /// will overwrite the default ones if exist.
+ ///
+ /// - Note: This option will not be applied to independent using of `ImageDownloader` or `ImageCache`.
+ public var defaultOptions = KingfisherEmptyOptionsInfo
+
+ var currentDefaultOptions: KingfisherOptionsInfo {
+ return [.downloader(downloader), .targetCache(cache)] + defaultOptions
+ }
+
convenience init() {
self.init(downloader: .default, cache: .default)
}
@@ -108,8 +116,8 @@ public class KingfisherManager {
completionHandler: CompletionHandler?) -> RetrieveImageTask
{
let task = RetrieveImageTask()
-
- if let options = options, options.forceRefresh {
+ let options = currentDefaultOptions + (options ?? KingfisherEmptyOptionsInfo)
+ if options.forceRefresh {
_ = downloadAndCacheImage(
with: resource.downloadURL,
forKey: resource.cacheKey,
@@ -136,9 +144,8 @@ public class KingfisherManager {
retrieveImageTask: RetrieveImageTask,
progressBlock: DownloadProgressBlock?,
completionHandler: CompletionHandler?,
- options: KingfisherOptionsInfo?) -> RetrieveImageDownloadTask?
+ options: KingfisherOptionsInfo) -> RetrieveImageDownloadTask?
{
- let options = options ?? KingfisherEmptyOptionsInfo
let downloader = options.downloader
return downloader.downloadImage(with: url, retrieveImageTask: retrieveImageTask, options: options,
progressBlock: { receivedSize, totalSize in
@@ -164,6 +171,19 @@ public class KingfisherManager {
cacheSerializer: options.cacheSerializer,
toDisk: !options.cacheMemoryOnly,
completionHandler: nil)
+ if options.cacheOriginalImage && options.processor != DefaultImageProcessor.default {
+ let originalCache = options.originalCache
+ let defaultProcessor = DefaultImageProcessor.default
+ if let originalImage = defaultProcessor.process(item: .data(originalData), options: options) {
+ originalCache.store(originalImage,
+ original: originalData,
+ forKey: key,
+ processorIdentifier: defaultProcessor.identifier,
+ cacheSerializer: options.cacheSerializer,
+ toDisk: !options.cacheMemoryOnly,
+ completionHandler: nil)
+ }
+ }
}
completionHandler?(image, error, .none, url)
@@ -176,30 +196,71 @@ public class KingfisherManager {
retrieveImageTask: RetrieveImageTask,
progressBlock: DownloadProgressBlock?,
completionHandler: CompletionHandler?,
- options: KingfisherOptionsInfo?)
+ options: KingfisherOptionsInfo)
{
+
+
let diskTaskCompletionHandler: CompletionHandler = { (image, error, cacheType, imageURL) -> () in
completionHandler?(image, error, cacheType, imageURL)
}
- let targetCache = options?.targetCache ?? cache
- targetCache.retrieveImage(forKey: key, options: options,
- completionHandler: { image, cacheType in
- if image != nil {
- diskTaskCompletionHandler(image, nil, cacheType, url)
- } else if let options = options, options.onlyFromCache {
- let error = NSError(domain: KingfisherErrorDomain, code: KingfisherError.notCached.rawValue, userInfo: nil)
- diskTaskCompletionHandler(nil, error, .none, url)
- } else {
- self.downloadAndCacheImage(
- with: url,
- forKey: key,
- retrieveImageTask: retrieveImageTask,
- progressBlock: progressBlock,
- completionHandler: diskTaskCompletionHandler,
- options: options)
+ func handleNoCache() {
+ if options.onlyFromCache {
+ let error = NSError(domain: KingfisherErrorDomain, code: KingfisherError.notCached.rawValue, userInfo: nil)
+ diskTaskCompletionHandler(nil, error, .none, url)
+ return
+ }
+ self.downloadAndCacheImage(
+ with: url,
+ forKey: key,
+ retrieveImageTask: retrieveImageTask,
+ progressBlock: progressBlock,
+ completionHandler: diskTaskCompletionHandler,
+ options: options)
+
+ }
+
+ let targetCache = options.targetCache
+ // First, try to get the exactly image from cache
+ targetCache.retrieveImage(forKey: key, options: options) { image, cacheType in
+ // If found, we could finish now.
+ if image != nil {
+ diskTaskCompletionHandler(image, nil, cacheType, url)
+ return
+ }
+
+ // If not found, and we are using a default processor, download it!
+ let processor = options.processor
+ guard processor != DefaultImageProcessor.default else {
+ handleNoCache()
+ return
+ }
+
+ // If processor is not the default one, we have a chance to check whether
+ // the original image is already in cache.
+ let originalCache = options.originalCache
+ let optionsWithoutProcessor = options.removeAllMatchesIgnoringAssociatedValue(.processor(processor))
+ originalCache.retrieveImage(forKey: key, options: optionsWithoutProcessor) { image, cacheType in
+ // If we found the original image, there is no need to download it again.
+ // We could just apply processor to it now.
+ guard let image = image else {
+ handleNoCache()
+ return
}
+
+ guard let processedImage = processor.process(item: .image(image), options: options) else {
+ diskTaskCompletionHandler(nil, nil, .none, url)
+ return
+ }
+ targetCache.store(processedImage,
+ original: nil,
+ forKey: key,
+ processorIdentifier:options.processor.identifier,
+ cacheSerializer: options.cacheSerializer,
+ toDisk: !options.cacheMemoryOnly,
+ completionHandler: nil)
+ diskTaskCompletionHandler(processedImage, nil, .none, url)
}
- )
+ }
}
}
diff --git a/WRNavigationBar_swift/Pods/Kingfisher/Sources/KingfisherOptionsInfo.swift b/WRNavigationBar_swift/Pods/Kingfisher/Sources/KingfisherOptionsInfo.swift
index 948906e..1d275dc 100755
--- a/WRNavigationBar_swift/Pods/Kingfisher/Sources/KingfisherOptionsInfo.swift
+++ b/WRNavigationBar_swift/Pods/Kingfisher/Sources/KingfisherOptionsInfo.swift
@@ -46,6 +46,11 @@ public enum KingfisherOptionsInfoItem {
/// the downloaded image to it.
case targetCache(ImageCache)
+ /// Cache for storing and retrieving original image.
+ /// Preferred prior to targetCache for storing and retrieving original images if specified.
+ /// Only used if a non-default image processor is involved.
+ case originalCache(ImageCache)
+
/// The associated value of this member should be an ImageDownloader object. Kingfisher will use this
/// downloader to download the images.
case downloader(ImageDownloader)
@@ -62,6 +67,11 @@ public enum KingfisherOptionsInfoItem {
/// If set, `Kingfisher` will ignore the cache and try to fire a download task for the resource.
case forceRefresh
+
+ /// If set, `Kingfisher` will try to retrieve the image from memory cache first. If the image is not in memory
+ /// cache, then it will ignore the disk cache but download the image again from network. This is useful when
+ /// you want to display a changeable image behind the same url, while avoiding download it again and again.
+ case fromMemoryCacheOrRefresh
/// If set, setting the image to an image view will happen with transition even when retrieved from cache.
/// See `Transition` option for more.
@@ -84,13 +94,13 @@ public enum KingfisherOptionsInfoItem {
/// It is the image scale, instead of your screen scale. You may need to specify the correct scale when you dealing
/// with 2x or 3x retina images.
case scaleFactor(CGFloat)
-
- /// Whether all the GIF data should be preloaded. Default it false, which means following frames will be
- /// loaded on need. If true, all the GIF data will be loaded and decoded into memory. This option is mainly
+
+ /// Whether all the animated image data should be preloaded. Default it false, which means following frames will be
+ /// loaded on need. If true, all the animated image data will be loaded and decoded into memory. This option is mainly
/// used for back compatibility internally. You should not set it directly. `AnimatedImageView` will not preload
/// all data, while a normal image view (`UIImageView` or `NSImageView`) will load all data. Choose to use
/// corresponding image view type instead of setting this option.
- case preloadAllGIFData
+ case preloadAllAnimationData
/// The `ImageDownloadRequestModifier` contained will be used to change the request before it being sent.
/// This is the last chance you can modify the request. You can modify the request for some customizing purpose,
@@ -114,11 +124,17 @@ public enum KingfisherOptionsInfoItem {
/// will be ignored and the current image will be kept while loading or downloading the new image.
case keepCurrentImageWhileLoading
- /// If set, Kingfisher will only load the first frame from a GIF file as a single image.
- /// Loading a lot of GIFs may take too much memory. It will be useful when you want to display a
- /// static preview of the first frame from a GIF image.
- /// This option will be ignored if the target image is not GIF.
+ /// If set, Kingfisher will only load the first frame from a animated image data file as a single image.
+ /// Loading a lot of animated images may take too much memory. It will be useful when you want to display a
+ /// static preview of the first frame from a animated image.
+ /// This option will be ignored if the target image is not animated image data.
case onlyLoadFirstFrame
+
+ /// If set and an `ImageProcessor` is used, Kingfisher will try to cache both
+ /// the final result and original image. Kingfisher will have a chance to use
+ /// the original image when another processor is applied to the same resouce,
+ /// instead of downloading it again.
+ case cacheOriginalImage
}
precedencegroup ItemComparisonPrecedence {
@@ -132,40 +148,44 @@ infix operator <== : ItemComparisonPrecedence
func <== (lhs: KingfisherOptionsInfoItem, rhs: KingfisherOptionsInfoItem) -> Bool {
switch (lhs, rhs) {
case (.targetCache(_), .targetCache(_)): return true
+ case (.originalCache(_), .originalCache(_)): return true
case (.downloader(_), .downloader(_)): return true
case (.transition(_), .transition(_)): return true
case (.downloadPriority(_), .downloadPriority(_)): return true
case (.forceRefresh, .forceRefresh): return true
+ case (.fromMemoryCacheOrRefresh, .fromMemoryCacheOrRefresh): return true
case (.forceTransition, .forceTransition): return true
case (.cacheMemoryOnly, .cacheMemoryOnly): return true
case (.onlyFromCache, .onlyFromCache): return true
case (.backgroundDecode, .backgroundDecode): return true
case (.callbackDispatchQueue(_), .callbackDispatchQueue(_)): return true
case (.scaleFactor(_), .scaleFactor(_)): return true
- case (.preloadAllGIFData, .preloadAllGIFData): return true
+ case (.preloadAllAnimationData, .preloadAllAnimationData): return true
case (.requestModifier(_), .requestModifier(_)): return true
case (.processor(_), .processor(_)): return true
case (.cacheSerializer(_), .cacheSerializer(_)): return true
case (.keepCurrentImageWhileLoading, .keepCurrentImageWhileLoading): return true
case (.onlyLoadFirstFrame, .onlyLoadFirstFrame): return true
+ case (.cacheOriginalImage, .cacheOriginalImage): return true
default: return false
}
}
+
extension Collection where Iterator.Element == KingfisherOptionsInfoItem {
- func firstMatchIgnoringAssociatedValue(_ target: Iterator.Element) -> Iterator.Element? {
- return index { $0 <== target }.flatMap { self[$0] }
+ func lastMatchIgnoringAssociatedValue(_ target: Iterator.Element) -> Iterator.Element? {
+ return reversed().first { $0 <== target }
}
func removeAllMatchesIgnoringAssociatedValue(_ target: Iterator.Element) -> [Iterator.Element] {
- return self.filter { !($0 <== target) }
+ return filter { !($0 <== target) }
}
}
public extension Collection where Iterator.Element == KingfisherOptionsInfoItem {
/// The target `ImageCache` which is used.
public var targetCache: ImageCache {
- if let item = firstMatchIgnoringAssociatedValue(.targetCache(.default)),
+ if let item = lastMatchIgnoringAssociatedValue(.targetCache(.default)),
case .targetCache(let cache) = item
{
return cache
@@ -173,9 +193,19 @@ public extension Collection where Iterator.Element == KingfisherOptionsInfoItem
return ImageCache.default
}
+ /// The original `ImageCache` which is used.
+ public var originalCache: ImageCache {
+ if let item = lastMatchIgnoringAssociatedValue(.originalCache(.default)),
+ case .originalCache(let cache) = item
+ {
+ return cache
+ }
+ return targetCache
+ }
+
/// The `ImageDownloader` which is specified.
public var downloader: ImageDownloader {
- if let item = firstMatchIgnoringAssociatedValue(.downloader(.default)),
+ if let item = lastMatchIgnoringAssociatedValue(.downloader(.default)),
case .downloader(let downloader) = item
{
return downloader
@@ -185,7 +215,7 @@ public extension Collection where Iterator.Element == KingfisherOptionsInfoItem
/// Member for animation transition when using UIImageView.
public var transition: ImageTransition {
- if let item = firstMatchIgnoringAssociatedValue(.transition(.none)),
+ if let item = lastMatchIgnoringAssociatedValue(.transition(.none)),
case .transition(let transition) = item
{
return transition
@@ -196,7 +226,7 @@ public extension Collection where Iterator.Element == KingfisherOptionsInfoItem
/// A `Float` value set as the priority of image download task. The value for it should be
/// between 0.0~1.0.
public var downloadPriority: Float {
- if let item = firstMatchIgnoringAssociatedValue(.downloadPriority(0)),
+ if let item = lastMatchIgnoringAssociatedValue(.downloadPriority(0)),
case .downloadPriority(let priority) = item
{
return priority
@@ -208,6 +238,11 @@ public extension Collection where Iterator.Element == KingfisherOptionsInfoItem
public var forceRefresh: Bool {
return contains{ $0 <== .forceRefresh }
}
+
+ /// Whether an image should be got only from memory cache or download.
+ public var fromMemoryCacheOrRefresh: Bool {
+ return contains{ $0 <== .fromMemoryCacheOrRefresh }
+ }
/// Whether the transition should always happen or not.
public var forceTransition: Bool {
@@ -228,15 +263,15 @@ public extension Collection where Iterator.Element == KingfisherOptionsInfoItem
public var backgroundDecode: Bool {
return contains{ $0 <== .backgroundDecode }
}
-
- /// Whether the image data should be all loaded at once if it is a GIF.
- public var preloadAllGIFData: Bool {
- return contains { $0 <== .preloadAllGIFData }
+
+ /// Whether the image data should be all loaded at once if it is an animated image.
+ public var preloadAllAnimationData: Bool {
+ return contains { $0 <== .preloadAllAnimationData }
}
/// The queue of callbacks should happen from Kingfisher.
public var callbackDispatchQueue: DispatchQueue {
- if let item = firstMatchIgnoringAssociatedValue(.callbackDispatchQueue(nil)),
+ if let item = lastMatchIgnoringAssociatedValue(.callbackDispatchQueue(nil)),
case .callbackDispatchQueue(let queue) = item
{
return queue ?? DispatchQueue.main
@@ -246,7 +281,7 @@ public extension Collection where Iterator.Element == KingfisherOptionsInfoItem
/// The scale factor which should be used for the image.
public var scaleFactor: CGFloat {
- if let item = firstMatchIgnoringAssociatedValue(.scaleFactor(0)),
+ if let item = lastMatchIgnoringAssociatedValue(.scaleFactor(0)),
case .scaleFactor(let scale) = item
{
return scale
@@ -256,7 +291,7 @@ public extension Collection where Iterator.Element == KingfisherOptionsInfoItem
/// The `ImageDownloadRequestModifier` will be used before sending a download request.
public var modifier: ImageDownloadRequestModifier {
- if let item = firstMatchIgnoringAssociatedValue(.requestModifier(NoModifier.default)),
+ if let item = lastMatchIgnoringAssociatedValue(.requestModifier(NoModifier.default)),
case .requestModifier(let modifier) = item
{
return modifier
@@ -266,7 +301,7 @@ public extension Collection where Iterator.Element == KingfisherOptionsInfoItem
/// `ImageProcessor` for processing when the downloading finishes.
public var processor: ImageProcessor {
- if let item = firstMatchIgnoringAssociatedValue(.processor(DefaultImageProcessor.default)),
+ if let item = lastMatchIgnoringAssociatedValue(.processor(DefaultImageProcessor.default)),
case .processor(let processor) = item
{
return processor
@@ -276,7 +311,7 @@ public extension Collection where Iterator.Element == KingfisherOptionsInfoItem
/// `CacheSerializer` to convert image to data for storing in cache.
public var cacheSerializer: CacheSerializer {
- if let item = firstMatchIgnoringAssociatedValue(.cacheSerializer(DefaultCacheSerializer.default)),
+ if let item = lastMatchIgnoringAssociatedValue(.cacheSerializer(DefaultCacheSerializer.default)),
case .cacheSerializer(let cacheSerializer) = item
{
return cacheSerializer
@@ -293,4 +328,8 @@ public extension Collection where Iterator.Element == KingfisherOptionsInfoItem
public var onlyLoadFirstFrame: Bool {
return contains { $0 <== .onlyLoadFirstFrame }
}
+
+ public var cacheOriginalImage: Bool {
+ return contains { $0 <== .cacheOriginalImage }
+ }
}
diff --git a/WRNavigationBar_swift/Pods/Kingfisher/Sources/Placeholder.swift b/WRNavigationBar_swift/Pods/Kingfisher/Sources/Placeholder.swift
new file mode 100755
index 0000000..b6076b5
--- /dev/null
+++ b/WRNavigationBar_swift/Pods/Kingfisher/Sources/Placeholder.swift
@@ -0,0 +1,82 @@
+//
+// Placeholder.swift
+// Kingfisher
+//
+// Created by Tieme van Veen on 28/08/2017.
+//
+// Copyright (c) 2017 Wei Wang
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+#if os(macOS)
+ import AppKit
+#else
+ import UIKit
+#endif
+
+
+/// Represent a placeholder type which could be set while loading as well as
+/// loading finished without getting an image.
+public protocol Placeholder {
+
+ /// How the placeholder should be added to a given image view.
+ func add(to imageView: ImageView)
+
+ /// How the placeholder should be removed from a given image view.
+ func remove(from imageView: ImageView)
+}
+
+/// Default implementation of an image placeholder. The image will be set or
+/// reset directly for `image` property of the image view.
+extension Placeholder where Self: Image {
+
+ /// How the placeholder should be added to a given image view.
+ public func add(to imageView: ImageView) { imageView.image = self }
+
+ /// How the placeholder should be removed from a given image view.
+ public func remove(from imageView: ImageView) { imageView.image = nil }
+}
+
+extension Image: Placeholder {}
+
+/// Default implementation of an arbitrary view as placeholder. The view will be
+/// added as a subview when adding and be removed from its super view when removing.
+///
+/// To use your customize View type as placeholder, simply let it conforming to
+/// `Placeholder` by `extension MyView: Placeholder {}`.
+extension Placeholder where Self: View {
+
+ /// How the placeholder should be added to a given image view.
+ public func add(to imageView: ImageView) {
+ imageView.addSubview(self)
+
+ self.translatesAutoresizingMaskIntoConstraints = false
+ NSLayoutConstraint.activate([
+ NSLayoutConstraint(item: self, attribute: .centerX, relatedBy: .equal, toItem: imageView, attribute: .centerX, multiplier: 1, constant: 0),
+ NSLayoutConstraint(item: self, attribute: .centerY, relatedBy: .equal, toItem: imageView, attribute: .centerY, multiplier: 1, constant: 0),
+ NSLayoutConstraint(item: self, attribute: .height, relatedBy: .equal, toItem: imageView, attribute: .height, multiplier: 1, constant: 0),
+ NSLayoutConstraint(item: self, attribute: .width, relatedBy: .equal, toItem: imageView, attribute: .width, multiplier: 1, constant: 0)
+ ])
+ }
+
+ /// How the placeholder should be removed from a given image view.
+ public func remove(from imageView: ImageView) {
+ self.removeFromSuperview()
+ }
+}
diff --git a/WRNavigationBar_swift/Pods/Kingfisher/Sources/UIButton+Kingfisher.swift b/WRNavigationBar_swift/Pods/Kingfisher/Sources/UIButton+Kingfisher.swift
index 97d3aab..c9a5e0e 100755
--- a/WRNavigationBar_swift/Pods/Kingfisher/Sources/UIButton+Kingfisher.swift
+++ b/WRNavigationBar_swift/Pods/Kingfisher/Sources/UIButton+Kingfisher.swift
@@ -46,6 +46,9 @@ extension Kingfisher where Base: UIButton {
- note: Both the `progressBlock` and `completionHandler` will be invoked in main thread.
The `CallbackDispatchQueue` specified in `optionsInfo` will not be used in callbacks of this method.
+
+ If `resource` is `nil`, the `placeholder` image will be set and
+ `completionHandler` will be called with both `error` and `image` being `nil`.
*/
@discardableResult
public func setImage(with resource: Resource?,
@@ -62,7 +65,7 @@ extension Kingfisher where Base: UIButton {
return .empty
}
- let options = options ?? KingfisherEmptyOptionsInfo
+ let options = KingfisherManager.shared.defaultOptions + (options ?? KingfisherEmptyOptionsInfo)
if !options.keepCurrentImageWhileLoading {
base.setImage(placeholder, for: state)
}
@@ -82,10 +85,10 @@ extension Kingfisher where Base: UIButton {
completionHandler: {[weak base] image, error, cacheType, imageURL in
DispatchQueue.main.safeAsync {
guard let strongBase = base, imageURL == self.webURL(for: state) else {
+ completionHandler?(image, error, cacheType, imageURL)
return
}
self.setImageTask(nil)
-
if image != nil {
strongBase.setImage(image, for: state)
}
@@ -121,6 +124,9 @@ extension Kingfisher where Base: UIButton {
- note: Both the `progressBlock` and `completionHandler` will be invoked in main thread.
The `CallbackDispatchQueue` specified in `optionsInfo` will not be used in callbacks of this method.
+
+ If `resource` is `nil`, the `placeholder` image will be set and
+ `completionHandler` will be called with both `error` and `image` being `nil`.
*/
@discardableResult
public func setBackgroundImage(with resource: Resource?,
@@ -137,7 +143,7 @@ extension Kingfisher where Base: UIButton {
return .empty
}
- let options = options ?? KingfisherEmptyOptionsInfo
+ let options = KingfisherManager.shared.defaultOptions + (options ?? KingfisherEmptyOptionsInfo)
if !options.keepCurrentImageWhileLoading {
base.setBackgroundImage(placeholder, for: state)
}
@@ -157,6 +163,7 @@ extension Kingfisher where Base: UIButton {
completionHandler: { [weak base] image, error, cacheType, imageURL in
DispatchQueue.main.safeAsync {
guard let strongBase = base, imageURL == self.backgroundWebURL(for: state) else {
+ completionHandler?(image, error, cacheType, imageURL)
return
}
self.setBackgroundImageTask(nil)
@@ -265,151 +272,3 @@ extension Kingfisher where Base: UIButton {
objc_setAssociatedObject(base, &backgroundImageTaskKey, task, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
}
}
-
-// MARK: - Deprecated. Only for back compatibility.
-/**
-* Set image to use from web for a specified state. Deprecated. Use `kf` namespacing instead.
-*/
-extension UIButton {
- /**
- Set an image to use for a specified state with a resource, a placeholder image, options, progress handler and
- completion handler.
-
- - parameter resource: Resource object contains information such as `cacheKey` and `downloadURL`.
- - parameter state: The state that uses the specified image.
- - parameter placeholder: A placeholder image when retrieving the image at URL.
- - parameter options: A dictionary could control some behaviors. See `KingfisherOptionsInfo` for more.
- - parameter progressBlock: Called when the image downloading progress gets updated.
- - parameter completionHandler: Called when the image retrieved and set.
-
- - returns: A task represents the retrieving process.
-
- - note: Both the `progressBlock` and `completionHandler` will be invoked in main thread.
- The `CallbackDispatchQueue` specified in `optionsInfo` will not be used in callbacks of this method.
- */
- @discardableResult
- @available(*, deprecated,
- message: "Extensions directly on UIButton are deprecated. Use `button.kf.setImage` instead.",
- renamed: "kf.setImage")
- public func kf_setImage(with resource: Resource?,
- for state: UIControlState,
- placeholder: UIImage? = nil,
- options: KingfisherOptionsInfo? = nil,
- progressBlock: DownloadProgressBlock? = nil,
- completionHandler: CompletionHandler? = nil) -> RetrieveImageTask
- {
- return kf.setImage(with: resource, for: state, placeholder: placeholder, options: options,
- progressBlock: progressBlock, completionHandler: completionHandler)
- }
-
- /**
- Cancel the image download task bounded to the image view if it is running.
- Nothing will happen if the downloading has already finished.
- */
- @available(*, deprecated,
- message: "Extensions directly on UIButton are deprecated. Use `button.kf.cancelImageDownloadTask` instead.",
- renamed: "kf.cancelImageDownloadTask")
- public func kf_cancelImageDownloadTask() { kf.cancelImageDownloadTask() }
-
- /**
- Set the background image to use for a specified state with a resource,
- a placeholder image, options progress handler and completion handler.
-
- - parameter resource: Resource object contains information such as `cacheKey` and `downloadURL`.
- - parameter state: The state that uses the specified image.
- - parameter placeholder: A placeholder image when retrieving the image at URL.
- - parameter options: A dictionary could control some behaviors. See `KingfisherOptionsInfo` for more.
- - parameter progressBlock: Called when the image downloading progress gets updated.
- - parameter completionHandler: Called when the image retrieved and set.
-
- - returns: A task represents the retrieving process.
-
- - note: Both the `progressBlock` and `completionHandler` will be invoked in main thread.
- The `CallbackDispatchQueue` specified in `optionsInfo` will not be used in callbacks of this method.
- */
- @discardableResult
- @available(*, deprecated,
- message: "Extensions directly on UIButton are deprecated. Use `button.kf.setBackgroundImage` instead.",
- renamed: "kf.setBackgroundImage")
- public func kf_setBackgroundImage(with resource: Resource?,
- for state: UIControlState,
- placeholder: UIImage? = nil,
- options: KingfisherOptionsInfo? = nil,
- progressBlock: DownloadProgressBlock? = nil,
- completionHandler: CompletionHandler? = nil) -> RetrieveImageTask
- {
- return kf.setBackgroundImage(with: resource, for: state, placeholder: placeholder, options: options,
- progressBlock: progressBlock, completionHandler: completionHandler)
- }
-
- /**
- Cancel the background image download task bounded to the image view if it is running.
- Nothing will happen if the downloading has already finished.
- */
- @available(*, deprecated,
- message: "Extensions directly on UIButton are deprecated. Use `button.kf.cancelBackgroundImageDownloadTask` instead.",
- renamed: "kf.cancelBackgroundImageDownloadTask")
- public func kf_cancelBackgroundImageDownloadTask() { kf.cancelBackgroundImageDownloadTask() }
-
- /**
- Get the image URL binded to this button for a specified state.
-
- - parameter state: The state that uses the specified image.
-
- - returns: Current URL for image.
- */
- @available(*, deprecated,
- message: "Extensions directly on UIButton are deprecated. Use `button.kf.webURL` instead.",
- renamed: "kf.webURL")
- public func kf_webURL(for state: UIControlState) -> URL? { return kf.webURL(for: state) }
-
- @available(*, deprecated, message: "Extensions directly on UIButton are deprecated.",renamed: "kf.setWebURL")
- fileprivate func kf_setWebURL(_ url: URL, for state: UIControlState) { kf.setWebURL(url, for: state) }
-
- @available(*, deprecated, message: "Extensions directly on UIButton are deprecated.",renamed: "kf.webURLs")
- fileprivate var kf_webURLs: NSMutableDictionary { return kf.webURLs }
-
- @available(*, deprecated, message: "Extensions directly on UIButton are deprecated.",renamed: "kf.setWebURLs")
- fileprivate func kf_setWebURLs(_ URLs: NSMutableDictionary) { kf.setWebURLs(URLs) }
-
- @available(*, deprecated, message: "Extensions directly on UIButton are deprecated.",renamed: "kf.imageTask")
- fileprivate var kf_imageTask: RetrieveImageTask? { return kf.imageTask }
-
- @available(*, deprecated, message: "Extensions directly on UIButton are deprecated.",renamed: "kf.setImageTask")
- fileprivate func kf_setImageTask(_ task: RetrieveImageTask?) { kf.setImageTask(task) }
-
- /**
- Get the background image URL binded to this button for a specified state.
-
- - parameter state: The state that uses the specified background image.
-
- - returns: Current URL for background image.
- */
- @available(*, deprecated,
- message: "Extensions directly on UIButton are deprecated. Use `button.kf.backgroundWebURL` instead.",
- renamed: "kf.backgroundWebURL")
- public func kf_backgroundWebURL(for state: UIControlState) -> URL? { return kf.backgroundWebURL(for: state) }
-
- @available(*, deprecated,
- message: "Extensions directly on UIButton are deprecated.",renamed: "kf.setBackgroundWebURL")
- fileprivate func kf_setBackgroundWebURL(_ url: URL, for state: UIControlState) {
- kf.setBackgroundWebURL(url, for: state)
- }
-
- @available(*, deprecated,
- message: "Extensions directly on UIButton are deprecated.",renamed: "kf.backgroundWebURLs")
- fileprivate var kf_backgroundWebURLs: NSMutableDictionary { return kf.backgroundWebURLs }
-
- @available(*, deprecated,
- message: "Extensions directly on UIButton are deprecated.",renamed: "kf.setBackgroundWebURLs")
- fileprivate func kf_setBackgroundWebURLs(_ URLs: NSMutableDictionary) { kf.setBackgroundWebURLs(URLs) }
-
- @available(*, deprecated,
- message: "Extensions directly on UIButton are deprecated.",renamed: "kf.backgroundImageTask")
- fileprivate var kf_backgroundImageTask: RetrieveImageTask? { return kf.backgroundImageTask }
-
- @available(*, deprecated,
- message: "Extensions directly on UIButton are deprecated.",renamed: "kf.setBackgroundImageTask")
- fileprivate func kf_setBackgroundImageTask(_ task: RetrieveImageTask?) { return kf.setBackgroundImageTask(task) }
-
-}
diff --git a/WRNavigationBar_swift/Pods/Manifest.lock b/WRNavigationBar_swift/Pods/Manifest.lock
index a57cf55..c6c2166 100644
--- a/WRNavigationBar_swift/Pods/Manifest.lock
+++ b/WRNavigationBar_swift/Pods/Manifest.lock
@@ -1,12 +1,12 @@
PODS:
- - Kingfisher (3.6.2)
+ - Kingfisher (4.3.1)
DEPENDENCIES:
- Kingfisher
SPEC CHECKSUMS:
- Kingfisher: 2c94e72c6830622c71d06adf4ea024c37d316830
+ Kingfisher: 75541c4b62f02e1fde6f9772303de3d9ebe8f5b3
PODFILE CHECKSUM: eedd5593b4e862f4a6b0ebf6fd6f3f022a9f6b1d
-COCOAPODS: 1.2.1
+COCOAPODS: 1.3.1
diff --git a/WRNavigationBar_swift/Pods/Pods.xcodeproj/project.pbxproj b/WRNavigationBar_swift/Pods/Pods.xcodeproj/project.pbxproj
index adb3bc2..dcc6904 100644
--- a/WRNavigationBar_swift/Pods/Pods.xcodeproj/project.pbxproj
+++ b/WRNavigationBar_swift/Pods/Pods.xcodeproj/project.pbxproj
@@ -7,34 +7,36 @@
objects = {
/* Begin PBXBuildFile section */
- 0E9CC28AC8E34FE8E1C87E933E04BC7A /* ImageProcessor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 449745419F19FD32556B5DB4C4713E19 /* ImageProcessor.swift */; };
- 179523942E7D1E3EB210EF05E2C7AE79 /* Kingfisher.h in Headers */ = {isa = PBXBuildFile; fileRef = 814A249890448FEA6045B315BCF3CBDD /* Kingfisher.h */; settings = {ATTRIBUTES = (Public, ); }; };
- 2D41430007CE8464586F521838A882C2 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 72913984B3E4B2AD01F71E405D688036 /* Foundation.framework */; };
- 2E5E570FFC49EF98550401421A243C0F /* CacheSerializer.swift in Sources */ = {isa = PBXBuildFile; fileRef = CDB06CA9125048730F6F8EDD92103BD0 /* CacheSerializer.swift */; };
- 33395912F2FFA355C4C36B7EDEAA3DA7 /* ImageView+Kingfisher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EACA73146F2EFD5728BDDE27435FBD5 /* ImageView+Kingfisher.swift */; };
- 33A14E817C0FA585D5DA3A55E453299D /* Image.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EC672E8EA725C5D07B841DD0564BE8A /* Image.swift */; };
- 3414E1D9CB15149A296E16C45967B021 /* ImagePrefetcher.swift in Sources */ = {isa = PBXBuildFile; fileRef = A095EF160FF9234364CDD94B8926E24A /* ImagePrefetcher.swift */; };
- 342AE33215135AD56B73580012DC22AB /* AnimatedImageView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 40F4491E340CD8AFA20CA333A7248C0A /* AnimatedImageView.swift */; };
- 378B44CAA91C2106076668FDE72E1E02 /* KingfisherOptionsInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = E7F836E9F331D1DFAA871B794EC40647 /* KingfisherOptionsInfo.swift */; };
- 4089E39F76F86466B8DDD39A1C1ABB6B /* Filter.swift in Sources */ = {isa = PBXBuildFile; fileRef = A59DB5A84662EBAFEC776E1D05FC2A56 /* Filter.swift */; };
- 52A280AB4852FDE92DF09B5E79D5C2AA /* Indicator.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE39F8F9D08B99E2AC56305CB28004D2 /* Indicator.swift */; };
+ 07432E8DEA8B25795C7C545AA67A0187 /* ImageTransition.swift in Sources */ = {isa = PBXBuildFile; fileRef = 88C862B0902EAF74B609F90285CFB7C6 /* ImageTransition.swift */; };
+ 0CA6357476373C221D44C498AA1D65FE /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 72913984B3E4B2AD01F71E405D688036 /* Foundation.framework */; };
+ 10AD5E70FDD53228153032C58FBF4D52 /* String+MD5.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8D9580FED9E6FCE2C7845BC03E63D50A /* String+MD5.swift */; };
+ 1827E7D94F3A12CA0C58EF33AE4B026D /* KingfisherOptionsInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECB8A9E00B1031B5EEF4FADC65A407A6 /* KingfisherOptionsInfo.swift */; };
+ 1DAF3BB88351664576507F774FEB051C /* Filter.swift in Sources */ = {isa = PBXBuildFile; fileRef = EADB697E25B5800CAEFBC6A13A1DCBA9 /* Filter.swift */; };
+ 1FCC0970C8435F10768CA84C2025A177 /* Resource.swift in Sources */ = {isa = PBXBuildFile; fileRef = 835802EEFCA95C3BECB444475FEB53AD /* Resource.swift */; };
+ 2082EB4AA16440FFD5479FAFC0181066 /* Indicator.swift in Sources */ = {isa = PBXBuildFile; fileRef = A1791E48E319018D19A4085F3A0308EC /* Indicator.swift */; };
+ 282E6F0E67F3799B0ABCB9ED96B666A9 /* RequestModifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = 835C82F8B413C5FC71B973BC63C7530C /* RequestModifier.swift */; };
+ 2F288ED3641B2B4775884C462AE377E6 /* Kingfisher-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = F1DA91233A58A2FDA9DBACE4D8B923A8 /* Kingfisher-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 383C9A8DB84B83233633C3A00A2C1608 /* KingfisherManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 023C24331AF069FFB31BE4575FF92A66 /* KingfisherManager.swift */; };
+ 40765AAA791D6DFC0022639E348F0E6A /* FormatIndicatedCacheSerializer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8DC875D6BCDEC1D273EDD95695790E7B /* FormatIndicatedCacheSerializer.swift */; };
+ 413C2A3759ABEC870AAE61F28C258C31 /* ImageDownloader.swift in Sources */ = {isa = PBXBuildFile; fileRef = CA951D80476B7B25AF48029C77615E15 /* ImageDownloader.swift */; };
+ 48EC78A50C61424D4DFDC33A325CAA72 /* ThreadHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = A4C9AE39E7B57A63ADA77C5411A94EBA /* ThreadHelper.swift */; };
+ 52416A6AC7387ECACCC45596498D96AD /* CFNetwork.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F46EFC5CDAF57A92A7B136FFD3525675 /* CFNetwork.framework */; };
+ 5B5D8AE167BD8E304CE474A9B8DBA2B4 /* Kingfisher.h in Headers */ = {isa = PBXBuildFile; fileRef = C82DCFCD04A890F33F6873466BB8F21E /* Kingfisher.h */; settings = {ATTRIBUTES = (Public, ); }; };
5D03025A98024CDF4F5DC9AC69A6D838 /* Pods-WRNavigationBar_swift-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 7CECED3FD3EA864979CAFC7D2E34BD93 /* Pods-WRNavigationBar_swift-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; };
- 6A375593407BC7937234B2B6A0811760 /* Kingfisher-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 9856B231053FF41FC9B14ACCC6F9215C /* Kingfisher-dummy.m */; };
- 6CD63E1564618B6213B98E0ABBC3127C /* ThreadHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5D06CAA9AFC94CB86E9CB96D78BD0923 /* ThreadHelper.swift */; };
- 6DA770087D354CDCD3889CDAE7C4C698 /* Box.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9DE6AD548C8531F1E89A4AC6B1C6B3A8 /* Box.swift */; };
- 7636F846675C9F4ED96E00C6C19A4890 /* KingfisherManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = FBB1ACC8AAF2B55915F99167EE149FA6 /* KingfisherManager.swift */; };
- 86B7DA678C8705523C300947117C0706 /* ImageTransition.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA1EE6FB137B9949B921A201014D9660 /* ImageTransition.swift */; };
- 8DA7E6883118CB3C8132B64D3D43AE0B /* Resource.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0CCAABA051F2B62FEC94F6629032960D /* Resource.swift */; };
- 9F826F893E86EB86591B637A1CE4B13A /* String+MD5.swift in Sources */ = {isa = PBXBuildFile; fileRef = AFD3C40826560CCA979FBF1A30879C5D /* String+MD5.swift */; };
- A8F35D1EBAEF99D38F02A0B8CA5D8FBE /* Kingfisher-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = A24D7C6D5AC7A569D95092B9FA066ABA /* Kingfisher-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 5D83206A9A4656F11D511158EC8E0784 /* CacheSerializer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2DFCC4FC32F83B831601673C6818F019 /* CacheSerializer.swift */; };
+ 873BA68C2E24D634D38E4A8BCB74B08D /* Kingfisher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 81AE08F84342F7AB3680E0E6F7574A5A /* Kingfisher.swift */; };
+ 8D7D42C25F9430F572E14200C399D57B /* ImageCache.swift in Sources */ = {isa = PBXBuildFile; fileRef = C98A82CA32E1D54EA4FB0140C87A0D5F /* ImageCache.swift */; };
+ 93D444FC9D79520E14FB8EF178F0B76E /* ImageProcessor.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5B32513990923B73428F091F7DE8A5B /* ImageProcessor.swift */; };
+ 950D8E334E011B13CC5786595E6AE615 /* Image.swift in Sources */ = {isa = PBXBuildFile; fileRef = A9B28D20BE64B86A107267022F1E7064 /* Image.swift */; };
+ A7EC09EC6EFAB3778E0A0341E7DC9CE3 /* AnimatedImageView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9295207D7CEECE2F5BDCD8CD84920ABE /* AnimatedImageView.swift */; };
+ B0033530A0EAABBB31CD46CA2899F3BD /* Box.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F0AEF804C3FF811567DCF8CBD32A1D5 /* Box.swift */; };
C1C52534BAF0801C90F6B3DDF3A59896 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 72913984B3E4B2AD01F71E405D688036 /* Foundation.framework */; };
- C9CC5ED97D29C6C3DE22B78A9AA2AD91 /* Kingfisher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6211E96F580D34F3E3F84D65BD80EC24 /* Kingfisher.swift */; };
+ CB4222BC34D92C2E06A5BCF730FEFE71 /* Kingfisher-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = E62FDCDEE52FFBAACE80CC15C761D7C6 /* Kingfisher-dummy.m */; };
+ CB8DF027448816C623E9B02A3685A59F /* ImageView+Kingfisher.swift in Sources */ = {isa = PBXBuildFile; fileRef = DF8738D6ED045E7C089A8AE94F21A0A0 /* ImageView+Kingfisher.swift */; };
D5B9985DA680B07E486A07969DA20D79 /* Pods-WRNavigationBar_swift-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = F8219BF94193F7436659F916DA2353FE /* Pods-WRNavigationBar_swift-dummy.m */; };
- DC6080C64C269628C3F5107BE87055E2 /* ImageDownloader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 94DE4AC69094EC3015FFF1BF0AD4AFE7 /* ImageDownloader.swift */; };
- EA816A580C3858934ED6FE92040C26DD /* RequestModifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = 799CA99214B1F57CE947563E43D6E995 /* RequestModifier.swift */; };
- EE89512E8D36E67CDC525DB9D5BBF5A7 /* UIButton+Kingfisher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E4022814E31F041CA8E6FFA328C8639 /* UIButton+Kingfisher.swift */; };
- F5C8C3F45F42FBDE5D87000C71178D20 /* CFNetwork.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F46EFC5CDAF57A92A7B136FFD3525675 /* CFNetwork.framework */; };
- F8E957950566622A3E4B61AACE8F0B4A /* ImageCache.swift in Sources */ = {isa = PBXBuildFile; fileRef = F0C72AFC42CED429C7A71F7A7704D20C /* ImageCache.swift */; };
+ E710FF1F4EB4B125F9C5DBDFE3B9320F /* Placeholder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 685A4E99CB4F94AC0F404F519C7AC866 /* Placeholder.swift */; };
+ F99792883819ADBD16123F91F6A9F3F8 /* ImagePrefetcher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 308FC14D7DDFBB406C2E4ED7415C8D7B /* ImagePrefetcher.swift */; };
+ FAC3C67720C7E6EF51CCAE58F62645BC /* UIButton+Kingfisher.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1AF856B3D835339E6E446917C5312B6 /* UIButton+Kingfisher.swift */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
@@ -42,54 +44,56 @@
isa = PBXContainerItemProxy;
containerPortal = D41D8CD98F00B204E9800998ECF8427E /* Project object */;
proxyType = 1;
- remoteGlobalIDString = C4944FEC314D1A66588651D006273ADE;
+ remoteGlobalIDString = 6F712943B3C5592E82604940D11CE08A;
remoteInfo = Kingfisher;
};
/* End PBXContainerItemProxy section */
/* Begin PBXFileReference section */
+ 023C24331AF069FFB31BE4575FF92A66 /* KingfisherManager.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = KingfisherManager.swift; path = Sources/KingfisherManager.swift; sourceTree = ""; };
077D151C882C36797498299FA868DD45 /* Pods-WRNavigationBar_swift.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-WRNavigationBar_swift.release.xcconfig"; sourceTree = ""; };
- 0CCAABA051F2B62FEC94F6629032960D /* Resource.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Resource.swift; path = Sources/Resource.swift; sourceTree = ""; };
- 0EACA73146F2EFD5728BDDE27435FBD5 /* ImageView+Kingfisher.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "ImageView+Kingfisher.swift"; path = "Sources/ImageView+Kingfisher.swift"; sourceTree = ""; };
+ 0F7DF0BCFC0710953CC5FF9972BE0B04 /* Kingfisher-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Kingfisher-prefix.pch"; sourceTree = ""; };
+ 2DFCC4FC32F83B831601673C6818F019 /* CacheSerializer.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = CacheSerializer.swift; path = Sources/CacheSerializer.swift; sourceTree = ""; };
2E03BC01661E426D39F6C97D69CBD5DA /* Pods-WRNavigationBar_swift-resources.sh */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.script.sh; path = "Pods-WRNavigationBar_swift-resources.sh"; sourceTree = ""; };
+ 308FC14D7DDFBB406C2E4ED7415C8D7B /* ImagePrefetcher.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ImagePrefetcher.swift; path = Sources/ImagePrefetcher.swift; sourceTree = ""; };
3CE01395EF504C101EFDBC103EC6E461 /* Pods-WRNavigationBar_swift.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; path = "Pods-WRNavigationBar_swift.modulemap"; sourceTree = ""; };
- 40F4491E340CD8AFA20CA333A7248C0A /* AnimatedImageView.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = AnimatedImageView.swift; path = Sources/AnimatedImageView.swift; sourceTree = ""; };
- 449745419F19FD32556B5DB4C4713E19 /* ImageProcessor.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ImageProcessor.swift; path = Sources/ImageProcessor.swift; sourceTree = ""; };
- 5207B9BA1FAC60A316B91128301138B6 /* Kingfisher.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; path = Kingfisher.modulemap; sourceTree = ""; };
+ 52DC30D7E6C1223D54467216A97B0B7D /* Kingfisher.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = Kingfisher.xcconfig; sourceTree = ""; };
5B49DEB9DF25D6EA7B6693213B7B90B3 /* Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
- 5D06CAA9AFC94CB86E9CB96D78BD0923 /* ThreadHelper.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ThreadHelper.swift; path = Sources/ThreadHelper.swift; sourceTree = ""; };
- 6211E96F580D34F3E3F84D65BD80EC24 /* Kingfisher.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Kingfisher.swift; path = Sources/Kingfisher.swift; sourceTree = ""; };
638E15C347D7A409389BE9A0476CC59F /* Kingfisher.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = Kingfisher.framework; path = Kingfisher.framework; sourceTree = BUILT_PRODUCTS_DIR; };
+ 685A4E99CB4F94AC0F404F519C7AC866 /* Placeholder.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Placeholder.swift; path = Sources/Placeholder.swift; sourceTree = ""; };
72913984B3E4B2AD01F71E405D688036 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS10.3.sdk/System/Library/Frameworks/Foundation.framework; sourceTree = DEVELOPER_DIR; };
75E959B193E767DED64E98D2D01CDA5F /* Pods_WRNavigationBar_swift.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = Pods_WRNavigationBar_swift.framework; path = "Pods-WRNavigationBar_swift.framework"; sourceTree = BUILT_PRODUCTS_DIR; };
- 799CA99214B1F57CE947563E43D6E995 /* RequestModifier.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RequestModifier.swift; path = Sources/RequestModifier.swift; sourceTree = ""; };
7CECED3FD3EA864979CAFC7D2E34BD93 /* Pods-WRNavigationBar_swift-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Pods-WRNavigationBar_swift-umbrella.h"; sourceTree = ""; };
- 814A249890448FEA6045B315BCF3CBDD /* Kingfisher.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = Kingfisher.h; path = Sources/Kingfisher.h; sourceTree = ""; };
+ 7FA6100B5CDA0A51737954E7E2D1DE2D /* Kingfisher.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; path = Kingfisher.modulemap; sourceTree = ""; };
+ 81AE08F84342F7AB3680E0E6F7574A5A /* Kingfisher.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Kingfisher.swift; path = Sources/Kingfisher.swift; sourceTree = ""; };
+ 835802EEFCA95C3BECB444475FEB53AD /* Resource.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Resource.swift; path = Sources/Resource.swift; sourceTree = ""; };
+ 835C82F8B413C5FC71B973BC63C7530C /* RequestModifier.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RequestModifier.swift; path = Sources/RequestModifier.swift; sourceTree = ""; };
+ 854A8362EFD3CAC49FA4502B9F0FCB96 /* Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
+ 88C862B0902EAF74B609F90285CFB7C6 /* ImageTransition.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ImageTransition.swift; path = Sources/ImageTransition.swift; sourceTree = ""; };
+ 8D9580FED9E6FCE2C7845BC03E63D50A /* String+MD5.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "String+MD5.swift"; path = "Sources/String+MD5.swift"; sourceTree = ""; };
+ 8DC875D6BCDEC1D273EDD95695790E7B /* FormatIndicatedCacheSerializer.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = FormatIndicatedCacheSerializer.swift; path = Sources/FormatIndicatedCacheSerializer.swift; sourceTree = ""; };
+ 9295207D7CEECE2F5BDCD8CD84920ABE /* AnimatedImageView.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = AnimatedImageView.swift; path = Sources/AnimatedImageView.swift; sourceTree = ""; };
93A4A3777CF96A4AAC1D13BA6DCCEA73 /* Podfile */ = {isa = PBXFileReference; explicitFileType = text.script.ruby; includeInIndex = 1; lastKnownFileType = text; name = Podfile; path = ../Podfile; sourceTree = SOURCE_ROOT; xcLanguageSpecificationIdentifier = xcode.lang.ruby; };
- 94DE4AC69094EC3015FFF1BF0AD4AFE7 /* ImageDownloader.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ImageDownloader.swift; path = Sources/ImageDownloader.swift; sourceTree = ""; };
- 968C4EE1CB49CA730B177A530E6BC12F /* Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
- 9856B231053FF41FC9B14ACCC6F9215C /* Kingfisher-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Kingfisher-dummy.m"; sourceTree = ""; };
- 9DE6AD548C8531F1E89A4AC6B1C6B3A8 /* Box.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Box.swift; path = Sources/Box.swift; sourceTree = ""; };
- 9E4022814E31F041CA8E6FFA328C8639 /* UIButton+Kingfisher.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "UIButton+Kingfisher.swift"; path = "Sources/UIButton+Kingfisher.swift"; sourceTree = ""; };
- 9EC672E8EA725C5D07B841DD0564BE8A /* Image.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Image.swift; path = Sources/Image.swift; sourceTree = ""; };
- A095EF160FF9234364CDD94B8926E24A /* ImagePrefetcher.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ImagePrefetcher.swift; path = Sources/ImagePrefetcher.swift; sourceTree = ""; };
- A24D7C6D5AC7A569D95092B9FA066ABA /* Kingfisher-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Kingfisher-umbrella.h"; sourceTree = ""; };
- A59DB5A84662EBAFEC776E1D05FC2A56 /* Filter.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Filter.swift; path = Sources/Filter.swift; sourceTree = ""; };
- AA1EE6FB137B9949B921A201014D9660 /* ImageTransition.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ImageTransition.swift; path = Sources/ImageTransition.swift; sourceTree = ""; };
+ 9F0AEF804C3FF811567DCF8CBD32A1D5 /* Box.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Box.swift; path = Sources/Box.swift; sourceTree = ""; };
+ A1791E48E319018D19A4085F3A0308EC /* Indicator.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Indicator.swift; path = Sources/Indicator.swift; sourceTree = ""; };
+ A4C9AE39E7B57A63ADA77C5411A94EBA /* ThreadHelper.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ThreadHelper.swift; path = Sources/ThreadHelper.swift; sourceTree = ""; };
+ A5B32513990923B73428F091F7DE8A5B /* ImageProcessor.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ImageProcessor.swift; path = Sources/ImageProcessor.swift; sourceTree = ""; };
+ A9B28D20BE64B86A107267022F1E7064 /* Image.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Image.swift; path = Sources/Image.swift; sourceTree = ""; };
AE66F7EA3A06D631F5729F90A9F79406 /* Pods-WRNavigationBar_swift.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-WRNavigationBar_swift.debug.xcconfig"; sourceTree = ""; };
- AFD3C40826560CCA979FBF1A30879C5D /* String+MD5.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "String+MD5.swift"; path = "Sources/String+MD5.swift"; sourceTree = ""; };
BA4CB1BACA72306DD38BD93DB7EDC37F /* Pods-WRNavigationBar_swift-acknowledgements.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-WRNavigationBar_swift-acknowledgements.plist"; sourceTree = ""; };
- BC79E2E5D62D71F36463838727DAA58D /* Kingfisher.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = Kingfisher.xcconfig; sourceTree = ""; };
- CDB06CA9125048730F6F8EDD92103BD0 /* CacheSerializer.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = CacheSerializer.swift; path = Sources/CacheSerializer.swift; sourceTree = ""; };
- D7A3C90E9DF742791B93F3793008064F /* Kingfisher-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Kingfisher-prefix.pch"; sourceTree = ""; };
- DE39F8F9D08B99E2AC56305CB28004D2 /* Indicator.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Indicator.swift; path = Sources/Indicator.swift; sourceTree = ""; };
- E7F836E9F331D1DFAA871B794EC40647 /* KingfisherOptionsInfo.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = KingfisherOptionsInfo.swift; path = Sources/KingfisherOptionsInfo.swift; sourceTree = ""; };
- F0C72AFC42CED429C7A71F7A7704D20C /* ImageCache.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ImageCache.swift; path = Sources/ImageCache.swift; sourceTree = ""; };
+ C1AF856B3D835339E6E446917C5312B6 /* UIButton+Kingfisher.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "UIButton+Kingfisher.swift"; path = "Sources/UIButton+Kingfisher.swift"; sourceTree = ""; };
+ C82DCFCD04A890F33F6873466BB8F21E /* Kingfisher.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = Kingfisher.h; path = Sources/Kingfisher.h; sourceTree = ""; };
+ C98A82CA32E1D54EA4FB0140C87A0D5F /* ImageCache.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ImageCache.swift; path = Sources/ImageCache.swift; sourceTree = ""; };
+ CA951D80476B7B25AF48029C77615E15 /* ImageDownloader.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ImageDownloader.swift; path = Sources/ImageDownloader.swift; sourceTree = ""; };
+ DF8738D6ED045E7C089A8AE94F21A0A0 /* ImageView+Kingfisher.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "ImageView+Kingfisher.swift"; path = "Sources/ImageView+Kingfisher.swift"; sourceTree = ""; };
+ E62FDCDEE52FFBAACE80CC15C761D7C6 /* Kingfisher-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Kingfisher-dummy.m"; sourceTree = ""; };
+ EADB697E25B5800CAEFBC6A13A1DCBA9 /* Filter.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Filter.swift; path = Sources/Filter.swift; sourceTree = ""; };
+ ECB8A9E00B1031B5EEF4FADC65A407A6 /* KingfisherOptionsInfo.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = KingfisherOptionsInfo.swift; path = Sources/KingfisherOptionsInfo.swift; sourceTree = ""; };
F108F08B8C9ACDA3F91D31E82E22633F /* Pods-WRNavigationBar_swift-acknowledgements.markdown */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; path = "Pods-WRNavigationBar_swift-acknowledgements.markdown"; sourceTree = ""; };
+ F1DA91233A58A2FDA9DBACE4D8B923A8 /* Kingfisher-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Kingfisher-umbrella.h"; sourceTree = ""; };
F3572B8CC9A94DF04AEAD640C7F3B46F /* Pods-WRNavigationBar_swift-frameworks.sh */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.script.sh; path = "Pods-WRNavigationBar_swift-frameworks.sh"; sourceTree = ""; };
F46EFC5CDAF57A92A7B136FFD3525675 /* CFNetwork.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CFNetwork.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS10.3.sdk/System/Library/Frameworks/CFNetwork.framework; sourceTree = DEVELOPER_DIR; };
F8219BF94193F7436659F916DA2353FE /* Pods-WRNavigationBar_swift-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Pods-WRNavigationBar_swift-dummy.m"; sourceTree = ""; };
- FBB1ACC8AAF2B55915F99167EE149FA6 /* KingfisherManager.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = KingfisherManager.swift; path = Sources/KingfisherManager.swift; sourceTree = ""; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@@ -101,18 +105,32 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
- ED03E5917B811BACFE75189AE0C2A469 /* Frameworks */ = {
+ C0B9722E352CF90C920286E6F029D3C0 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
- F5C8C3F45F42FBDE5D87000C71178D20 /* CFNetwork.framework in Frameworks */,
- 2D41430007CE8464586F521838A882C2 /* Foundation.framework in Frameworks */,
+ 52416A6AC7387ECACCC45596498D96AD /* CFNetwork.framework in Frameworks */,
+ 0CA6357476373C221D44C498AA1D65FE /* Foundation.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
+ 0DEE2A01FA885B4899312B6F6826FDBF /* Support Files */ = {
+ isa = PBXGroup;
+ children = (
+ 854A8362EFD3CAC49FA4502B9F0FCB96 /* Info.plist */,
+ 7FA6100B5CDA0A51737954E7E2D1DE2D /* Kingfisher.modulemap */,
+ 52DC30D7E6C1223D54467216A97B0B7D /* Kingfisher.xcconfig */,
+ E62FDCDEE52FFBAACE80CC15C761D7C6 /* Kingfisher-dummy.m */,
+ 0F7DF0BCFC0710953CC5FF9972BE0B04 /* Kingfisher-prefix.pch */,
+ F1DA91233A58A2FDA9DBACE4D8B923A8 /* Kingfisher-umbrella.h */,
+ );
+ name = "Support Files";
+ path = "../Target Support Files/Kingfisher";
+ sourceTree = "";
+ };
1BF2B0C737CAAE286BA4320319120121 /* Targets Support Files */ = {
isa = PBXGroup;
children = (
@@ -148,6 +166,38 @@
name = Products;
sourceTree = "";
};
+ 3B1085458B794CEAF49F0B0EE79A1FBD /* Kingfisher */ = {
+ isa = PBXGroup;
+ children = (
+ 9295207D7CEECE2F5BDCD8CD84920ABE /* AnimatedImageView.swift */,
+ 9F0AEF804C3FF811567DCF8CBD32A1D5 /* Box.swift */,
+ 2DFCC4FC32F83B831601673C6818F019 /* CacheSerializer.swift */,
+ EADB697E25B5800CAEFBC6A13A1DCBA9 /* Filter.swift */,
+ 8DC875D6BCDEC1D273EDD95695790E7B /* FormatIndicatedCacheSerializer.swift */,
+ A9B28D20BE64B86A107267022F1E7064 /* Image.swift */,
+ C98A82CA32E1D54EA4FB0140C87A0D5F /* ImageCache.swift */,
+ CA951D80476B7B25AF48029C77615E15 /* ImageDownloader.swift */,
+ 308FC14D7DDFBB406C2E4ED7415C8D7B /* ImagePrefetcher.swift */,
+ A5B32513990923B73428F091F7DE8A5B /* ImageProcessor.swift */,
+ 88C862B0902EAF74B609F90285CFB7C6 /* ImageTransition.swift */,
+ DF8738D6ED045E7C089A8AE94F21A0A0 /* ImageView+Kingfisher.swift */,
+ A1791E48E319018D19A4085F3A0308EC /* Indicator.swift */,
+ C82DCFCD04A890F33F6873466BB8F21E /* Kingfisher.h */,
+ 81AE08F84342F7AB3680E0E6F7574A5A /* Kingfisher.swift */,
+ 023C24331AF069FFB31BE4575FF92A66 /* KingfisherManager.swift */,
+ ECB8A9E00B1031B5EEF4FADC65A407A6 /* KingfisherOptionsInfo.swift */,
+ 685A4E99CB4F94AC0F404F519C7AC866 /* Placeholder.swift */,
+ 835C82F8B413C5FC71B973BC63C7530C /* RequestModifier.swift */,
+ 835802EEFCA95C3BECB444475FEB53AD /* Resource.swift */,
+ 8D9580FED9E6FCE2C7845BC03E63D50A /* String+MD5.swift */,
+ A4C9AE39E7B57A63ADA77C5411A94EBA /* ThreadHelper.swift */,
+ C1AF856B3D835339E6E446917C5312B6 /* UIButton+Kingfisher.swift */,
+ 0DEE2A01FA885B4899312B6F6826FDBF /* Support Files */,
+ );
+ name = Kingfisher;
+ path = Kingfisher;
+ sourceTree = "";
+ };
3DC75C8869B42AB93D04871325A0707E /* iOS */ = {
isa = PBXGroup;
children = (
@@ -165,67 +215,23 @@
name = Frameworks;
sourceTree = "";
};
- 6D6A3E96995405C682083EAC9705D118 /* Pods */ = {
- isa = PBXGroup;
- children = (
- BC43CE0E4B9A087C6F738A912A8078EB /* Kingfisher */,
- );
- name = Pods;
- sourceTree = "";
- };
7DB346D0F39D3F0E887471402A8071AB = {
isa = PBXGroup;
children = (
93A4A3777CF96A4AAC1D13BA6DCCEA73 /* Podfile */,
433CD3331B6C3787F473C941B61FC68F /* Frameworks */,
- 6D6A3E96995405C682083EAC9705D118 /* Pods */,
+ 9469D748404B6E4D4F3E90E0B84F53A3 /* Pods */,
33668159F3B925188A23B48976230B79 /* Products */,
1BF2B0C737CAAE286BA4320319120121 /* Targets Support Files */,
);
sourceTree = "";
};
- BC43CE0E4B9A087C6F738A912A8078EB /* Kingfisher */ = {
+ 9469D748404B6E4D4F3E90E0B84F53A3 /* Pods */ = {
isa = PBXGroup;
children = (
- 40F4491E340CD8AFA20CA333A7248C0A /* AnimatedImageView.swift */,
- 9DE6AD548C8531F1E89A4AC6B1C6B3A8 /* Box.swift */,
- CDB06CA9125048730F6F8EDD92103BD0 /* CacheSerializer.swift */,
- A59DB5A84662EBAFEC776E1D05FC2A56 /* Filter.swift */,
- 9EC672E8EA725C5D07B841DD0564BE8A /* Image.swift */,
- F0C72AFC42CED429C7A71F7A7704D20C /* ImageCache.swift */,
- 94DE4AC69094EC3015FFF1BF0AD4AFE7 /* ImageDownloader.swift */,
- A095EF160FF9234364CDD94B8926E24A /* ImagePrefetcher.swift */,
- 449745419F19FD32556B5DB4C4713E19 /* ImageProcessor.swift */,
- AA1EE6FB137B9949B921A201014D9660 /* ImageTransition.swift */,
- 0EACA73146F2EFD5728BDDE27435FBD5 /* ImageView+Kingfisher.swift */,
- DE39F8F9D08B99E2AC56305CB28004D2 /* Indicator.swift */,
- 814A249890448FEA6045B315BCF3CBDD /* Kingfisher.h */,
- 6211E96F580D34F3E3F84D65BD80EC24 /* Kingfisher.swift */,
- FBB1ACC8AAF2B55915F99167EE149FA6 /* KingfisherManager.swift */,
- E7F836E9F331D1DFAA871B794EC40647 /* KingfisherOptionsInfo.swift */,
- 799CA99214B1F57CE947563E43D6E995 /* RequestModifier.swift */,
- 0CCAABA051F2B62FEC94F6629032960D /* Resource.swift */,
- AFD3C40826560CCA979FBF1A30879C5D /* String+MD5.swift */,
- 5D06CAA9AFC94CB86E9CB96D78BD0923 /* ThreadHelper.swift */,
- 9E4022814E31F041CA8E6FFA328C8639 /* UIButton+Kingfisher.swift */,
- DF56DAAF6901EA25B7722FFAC391B276 /* Support Files */,
+ 3B1085458B794CEAF49F0B0EE79A1FBD /* Kingfisher */,
);
- name = Kingfisher;
- path = Kingfisher;
- sourceTree = "";
- };
- DF56DAAF6901EA25B7722FFAC391B276 /* Support Files */ = {
- isa = PBXGroup;
- children = (
- 968C4EE1CB49CA730B177A530E6BC12F /* Info.plist */,
- 5207B9BA1FAC60A316B91128301138B6 /* Kingfisher.modulemap */,
- BC79E2E5D62D71F36463838727DAA58D /* Kingfisher.xcconfig */,
- 9856B231053FF41FC9B14ACCC6F9215C /* Kingfisher-dummy.m */,
- D7A3C90E9DF742791B93F3793008064F /* Kingfisher-prefix.pch */,
- A24D7C6D5AC7A569D95092B9FA066ABA /* Kingfisher-umbrella.h */,
- );
- name = "Support Files";
- path = "../Target Support Files/Kingfisher";
+ name = Pods;
sourceTree = "";
};
/* End PBXGroup section */
@@ -239,51 +245,51 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
- 0F94B6BFE5A6242FBBB0BE3D27F7CEE9 /* Headers */ = {
+ 84676F7D46FF521291CDEB2AB04A454C /* Headers */ = {
isa = PBXHeadersBuildPhase;
buildActionMask = 2147483647;
files = (
- A8F35D1EBAEF99D38F02A0B8CA5D8FBE /* Kingfisher-umbrella.h in Headers */,
- 179523942E7D1E3EB210EF05E2C7AE79 /* Kingfisher.h in Headers */,
+ 2F288ED3641B2B4775884C462AE377E6 /* Kingfisher-umbrella.h in Headers */,
+ 5B5D8AE167BD8E304CE474A9B8DBA2B4 /* Kingfisher.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXHeadersBuildPhase section */
/* Begin PBXNativeTarget section */
- B4F69341F1BC6A4E6AA3F83A92D32FFB /* Pods-WRNavigationBar_swift */ = {
+ 6F712943B3C5592E82604940D11CE08A /* Kingfisher */ = {
isa = PBXNativeTarget;
- buildConfigurationList = 3BC883AEA3BFFB398C35E6F6E3F9689C /* Build configuration list for PBXNativeTarget "Pods-WRNavigationBar_swift" */;
+ buildConfigurationList = 8C1E4CEFB2390CBE75E70BAC20F44BBF /* Build configuration list for PBXNativeTarget "Kingfisher" */;
buildPhases = (
- 19F926DB586A9A35FDF12C265BB83504 /* Sources */,
- 1E9938AFCEAD1D190C671C902B3A903E /* Frameworks */,
- 05C013F10E4A08DCD31F044A7072C25E /* Headers */,
+ FD12B015E1FDA3498428EF09C91D1F17 /* Sources */,
+ C0B9722E352CF90C920286E6F029D3C0 /* Frameworks */,
+ 84676F7D46FF521291CDEB2AB04A454C /* Headers */,
);
buildRules = (
);
dependencies = (
- 570F164AD107B6339FFB8826978C5EF4 /* PBXTargetDependency */,
);
- name = "Pods-WRNavigationBar_swift";
- productName = "Pods-WRNavigationBar_swift";
- productReference = 75E959B193E767DED64E98D2D01CDA5F /* Pods_WRNavigationBar_swift.framework */;
+ name = Kingfisher;
+ productName = Kingfisher;
+ productReference = 638E15C347D7A409389BE9A0476CC59F /* Kingfisher.framework */;
productType = "com.apple.product-type.framework";
};
- C4944FEC314D1A66588651D006273ADE /* Kingfisher */ = {
+ B4F69341F1BC6A4E6AA3F83A92D32FFB /* Pods-WRNavigationBar_swift */ = {
isa = PBXNativeTarget;
- buildConfigurationList = 76E7EFBCEA1340954A03AA68051C2306 /* Build configuration list for PBXNativeTarget "Kingfisher" */;
+ buildConfigurationList = 3BC883AEA3BFFB398C35E6F6E3F9689C /* Build configuration list for PBXNativeTarget "Pods-WRNavigationBar_swift" */;
buildPhases = (
- EAC7EA95310C5E1E724C632852F7D186 /* Sources */,
- ED03E5917B811BACFE75189AE0C2A469 /* Frameworks */,
- 0F94B6BFE5A6242FBBB0BE3D27F7CEE9 /* Headers */,
+ 19F926DB586A9A35FDF12C265BB83504 /* Sources */,
+ 1E9938AFCEAD1D190C671C902B3A903E /* Frameworks */,
+ 05C013F10E4A08DCD31F044A7072C25E /* Headers */,
);
buildRules = (
);
dependencies = (
+ 570F164AD107B6339FFB8826978C5EF4 /* PBXTargetDependency */,
);
- name = Kingfisher;
- productName = Kingfisher;
- productReference = 638E15C347D7A409389BE9A0476CC59F /* Kingfisher.framework */;
+ name = "Pods-WRNavigationBar_swift";
+ productName = "Pods-WRNavigationBar_swift";
+ productReference = 75E959B193E767DED64E98D2D01CDA5F /* Pods_WRNavigationBar_swift.framework */;
productType = "com.apple.product-type.framework";
};
/* End PBXNativeTarget section */
@@ -307,7 +313,7 @@
projectDirPath = "";
projectRoot = "";
targets = (
- C4944FEC314D1A66588651D006273ADE /* Kingfisher */,
+ 6F712943B3C5592E82604940D11CE08A /* Kingfisher */,
B4F69341F1BC6A4E6AA3F83A92D32FFB /* Pods-WRNavigationBar_swift */,
);
};
@@ -322,31 +328,33 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
- EAC7EA95310C5E1E724C632852F7D186 /* Sources */ = {
+ FD12B015E1FDA3498428EF09C91D1F17 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
- 342AE33215135AD56B73580012DC22AB /* AnimatedImageView.swift in Sources */,
- 6DA770087D354CDCD3889CDAE7C4C698 /* Box.swift in Sources */,
- 2E5E570FFC49EF98550401421A243C0F /* CacheSerializer.swift in Sources */,
- 4089E39F76F86466B8DDD39A1C1ABB6B /* Filter.swift in Sources */,
- 33A14E817C0FA585D5DA3A55E453299D /* Image.swift in Sources */,
- F8E957950566622A3E4B61AACE8F0B4A /* ImageCache.swift in Sources */,
- DC6080C64C269628C3F5107BE87055E2 /* ImageDownloader.swift in Sources */,
- 3414E1D9CB15149A296E16C45967B021 /* ImagePrefetcher.swift in Sources */,
- 0E9CC28AC8E34FE8E1C87E933E04BC7A /* ImageProcessor.swift in Sources */,
- 86B7DA678C8705523C300947117C0706 /* ImageTransition.swift in Sources */,
- 33395912F2FFA355C4C36B7EDEAA3DA7 /* ImageView+Kingfisher.swift in Sources */,
- 52A280AB4852FDE92DF09B5E79D5C2AA /* Indicator.swift in Sources */,
- 6A375593407BC7937234B2B6A0811760 /* Kingfisher-dummy.m in Sources */,
- C9CC5ED97D29C6C3DE22B78A9AA2AD91 /* Kingfisher.swift in Sources */,
- 7636F846675C9F4ED96E00C6C19A4890 /* KingfisherManager.swift in Sources */,
- 378B44CAA91C2106076668FDE72E1E02 /* KingfisherOptionsInfo.swift in Sources */,
- EA816A580C3858934ED6FE92040C26DD /* RequestModifier.swift in Sources */,
- 8DA7E6883118CB3C8132B64D3D43AE0B /* Resource.swift in Sources */,
- 9F826F893E86EB86591B637A1CE4B13A /* String+MD5.swift in Sources */,
- 6CD63E1564618B6213B98E0ABBC3127C /* ThreadHelper.swift in Sources */,
- EE89512E8D36E67CDC525DB9D5BBF5A7 /* UIButton+Kingfisher.swift in Sources */,
+ A7EC09EC6EFAB3778E0A0341E7DC9CE3 /* AnimatedImageView.swift in Sources */,
+ B0033530A0EAABBB31CD46CA2899F3BD /* Box.swift in Sources */,
+ 5D83206A9A4656F11D511158EC8E0784 /* CacheSerializer.swift in Sources */,
+ 1DAF3BB88351664576507F774FEB051C /* Filter.swift in Sources */,
+ 40765AAA791D6DFC0022639E348F0E6A /* FormatIndicatedCacheSerializer.swift in Sources */,
+ 950D8E334E011B13CC5786595E6AE615 /* Image.swift in Sources */,
+ 8D7D42C25F9430F572E14200C399D57B /* ImageCache.swift in Sources */,
+ 413C2A3759ABEC870AAE61F28C258C31 /* ImageDownloader.swift in Sources */,
+ F99792883819ADBD16123F91F6A9F3F8 /* ImagePrefetcher.swift in Sources */,
+ 93D444FC9D79520E14FB8EF178F0B76E /* ImageProcessor.swift in Sources */,
+ 07432E8DEA8B25795C7C545AA67A0187 /* ImageTransition.swift in Sources */,
+ CB8DF027448816C623E9B02A3685A59F /* ImageView+Kingfisher.swift in Sources */,
+ 2082EB4AA16440FFD5479FAFC0181066 /* Indicator.swift in Sources */,
+ CB4222BC34D92C2E06A5BCF730FEFE71 /* Kingfisher-dummy.m in Sources */,
+ 873BA68C2E24D634D38E4A8BCB74B08D /* Kingfisher.swift in Sources */,
+ 383C9A8DB84B83233633C3A00A2C1608 /* KingfisherManager.swift in Sources */,
+ 1827E7D94F3A12CA0C58EF33AE4B026D /* KingfisherOptionsInfo.swift in Sources */,
+ E710FF1F4EB4B125F9C5DBDFE3B9320F /* Placeholder.swift in Sources */,
+ 282E6F0E67F3799B0ABCB9ED96B666A9 /* RequestModifier.swift in Sources */,
+ 1FCC0970C8435F10768CA84C2025A177 /* Resource.swift in Sources */,
+ 10AD5E70FDD53228153032C58FBF4D52 /* String+MD5.swift in Sources */,
+ 48EC78A50C61424D4DFDC33A325CAA72 /* ThreadHelper.swift in Sources */,
+ FAC3C67720C7E6EF51CCAE58F62645BC /* UIButton+Kingfisher.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -356,126 +364,133 @@
570F164AD107B6339FFB8826978C5EF4 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
name = Kingfisher;
- target = C4944FEC314D1A66588651D006273ADE /* Kingfisher */;
+ target = 6F712943B3C5592E82604940D11CE08A /* Kingfisher */;
targetProxy = 39ED95EEBDF3F99D9600C1827FE92AF7 /* PBXContainerItemProxy */;
};
/* End PBXTargetDependency section */
/* Begin XCBuildConfiguration section */
- 20B5F4B4605A7E04AEE71183A359E092 /* Release */ = {
+ 576C583E88A92DC2279EB3BFC2CA8A6C /* Debug */ = {
isa = XCBuildConfiguration;
- baseConfigurationReference = BC79E2E5D62D71F36463838727DAA58D /* Kingfisher.xcconfig */;
+ baseConfigurationReference = 52DC30D7E6C1223D54467216A97B0B7D /* Kingfisher.xcconfig */;
buildSettings = {
CODE_SIGN_IDENTITY = "";
"CODE_SIGN_IDENTITY[sdk=appletvos*]" = "";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "";
"CODE_SIGN_IDENTITY[sdk=watchos*]" = "";
CURRENT_PROJECT_VERSION = 1;
- DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
DEFINES_MODULE = YES;
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
DYLIB_INSTALL_NAME_BASE = "@rpath";
- ENABLE_STRICT_OBJC_MSGSEND = YES;
- GCC_NO_COMMON_BLOCKS = YES;
GCC_PREFIX_HEADER = "Target Support Files/Kingfisher/Kingfisher-prefix.pch";
INFOPLIST_FILE = "Target Support Files/Kingfisher/Info.plist";
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
MODULEMAP_FILE = "Target Support Files/Kingfisher/Kingfisher.modulemap";
- MTL_ENABLE_DEBUG_INFO = NO;
PRODUCT_NAME = Kingfisher;
SDKROOT = iphoneos;
SKIP_INSTALL = YES;
+ SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) ";
+ SWIFT_OPTIMIZATION_LEVEL = "-Onone";
+ SWIFT_VERSION = 4.0;
+ TARGETED_DEVICE_FAMILY = "1,2";
+ VERSIONING_SYSTEM = "apple-generic";
+ VERSION_INFO_PREFIX = "";
+ };
+ name = Debug;
+ };
+ 961384A12D2CE6B1C90AD0CABD2F3B67 /* Release */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = 077D151C882C36797498299FA868DD45 /* Pods-WRNavigationBar_swift.release.xcconfig */;
+ buildSettings = {
+ CODE_SIGN_IDENTITY = "";
+ "CODE_SIGN_IDENTITY[sdk=appletvos*]" = "";
+ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "";
+ "CODE_SIGN_IDENTITY[sdk=watchos*]" = "";
+ CURRENT_PROJECT_VERSION = 1;
+ DEFINES_MODULE = YES;
+ DYLIB_COMPATIBILITY_VERSION = 1;
+ DYLIB_CURRENT_VERSION = 1;
+ DYLIB_INSTALL_NAME_BASE = "@rpath";
+ INFOPLIST_FILE = "Target Support Files/Pods-WRNavigationBar_swift/Info.plist";
+ INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
+ IPHONEOS_DEPLOYMENT_TARGET = 8.0;
+ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
+ MACH_O_TYPE = staticlib;
+ MODULEMAP_FILE = "Target Support Files/Pods-WRNavigationBar_swift/Pods-WRNavigationBar_swift.modulemap";
+ OTHER_LDFLAGS = "";
+ OTHER_LIBTOOLFLAGS = "";
+ PODS_ROOT = "$(SRCROOT)";
+ PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}";
+ PRODUCT_NAME = Pods_WRNavigationBar_swift;
+ SDKROOT = iphoneos;
+ SKIP_INSTALL = YES;
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
- SWIFT_VERSION = 3.0;
TARGETED_DEVICE_FAMILY = "1,2";
+ VALIDATE_PRODUCT = YES;
VERSIONING_SYSTEM = "apple-generic";
VERSION_INFO_PREFIX = "";
};
name = Release;
};
- 34FE9531DA9AF2820790339988D5FF41 /* Release */ = {
+ B254DAA6CF0CE39F4A3D11B90A7E059A /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
- CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES;
- CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
+ CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
- CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES;
+ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
- CLANG_WARN_OBJC_ROOT_CLASS = YES;
+ CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+ CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+ CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
+ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
CODE_SIGNING_REQUIRED = NO;
- COPY_PHASE_STRIP = YES;
+ COPY_PHASE_STRIP = NO;
+ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO;
- GCC_C_LANGUAGE_STANDARD = gnu99;
+ ENABLE_STRICT_OBJC_MSGSEND = YES;
+ GCC_C_LANGUAGE_STANDARD = gnu11;
+ GCC_NO_COMMON_BLOCKS = YES;
GCC_PREPROCESSOR_DEFINITIONS = (
"POD_CONFIGURATION_RELEASE=1",
"$(inherited)",
);
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
- GCC_WARN_ABOUT_RETURN_TYPE = YES;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
- GCC_WARN_UNINITIALIZED_AUTOS = YES;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
+ MTL_ENABLE_DEBUG_INFO = NO;
+ PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = NO_SIGNING/;
STRIP_INSTALLED_PRODUCT = NO;
SYMROOT = "${SRCROOT}/../build";
- VALIDATE_PRODUCT = YES;
};
name = Release;
};
- A794525992F2457D34942D108D9E942A /* Debug */ = {
- isa = XCBuildConfiguration;
- baseConfigurationReference = BC79E2E5D62D71F36463838727DAA58D /* Kingfisher.xcconfig */;
- buildSettings = {
- CODE_SIGN_IDENTITY = "";
- "CODE_SIGN_IDENTITY[sdk=appletvos*]" = "";
- "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "";
- "CODE_SIGN_IDENTITY[sdk=watchos*]" = "";
- CURRENT_PROJECT_VERSION = 1;
- DEBUG_INFORMATION_FORMAT = dwarf;
- DEFINES_MODULE = YES;
- DYLIB_COMPATIBILITY_VERSION = 1;
- DYLIB_CURRENT_VERSION = 1;
- DYLIB_INSTALL_NAME_BASE = "@rpath";
- ENABLE_STRICT_OBJC_MSGSEND = YES;
- GCC_NO_COMMON_BLOCKS = YES;
- GCC_PREFIX_HEADER = "Target Support Files/Kingfisher/Kingfisher-prefix.pch";
- INFOPLIST_FILE = "Target Support Files/Kingfisher/Info.plist";
- INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
- IPHONEOS_DEPLOYMENT_TARGET = 8.0;
- LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
- MODULEMAP_FILE = "Target Support Files/Kingfisher/Kingfisher.modulemap";
- MTL_ENABLE_DEBUG_INFO = YES;
- PRODUCT_NAME = Kingfisher;
- SDKROOT = iphoneos;
- SKIP_INSTALL = YES;
- SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
- SWIFT_OPTIMIZATION_LEVEL = "-Onone";
- SWIFT_VERSION = 3.0;
- TARGETED_DEVICE_FAMILY = "1,2";
- VERSIONING_SYSTEM = "apple-generic";
- VERSION_INFO_PREFIX = "";
- };
- name = Debug;
- };
- B1AC7D6C94B5F6C383D0C0DF11F6AE13 /* Debug */ = {
+ B44E7915DC09BA8049ACD6E6966BF9CC /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = AE66F7EA3A06D631F5729F90A9F79406 /* Pods-WRNavigationBar_swift.debug.xcconfig */;
buildSettings = {
@@ -484,20 +499,16 @@
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "";
"CODE_SIGN_IDENTITY[sdk=watchos*]" = "";
CURRENT_PROJECT_VERSION = 1;
- DEBUG_INFORMATION_FORMAT = dwarf;
DEFINES_MODULE = YES;
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
DYLIB_INSTALL_NAME_BASE = "@rpath";
- ENABLE_STRICT_OBJC_MSGSEND = YES;
- GCC_NO_COMMON_BLOCKS = YES;
INFOPLIST_FILE = "Target Support Files/Pods-WRNavigationBar_swift/Info.plist";
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
MACH_O_TYPE = staticlib;
MODULEMAP_FILE = "Target Support Files/Pods-WRNavigationBar_swift/Pods-WRNavigationBar_swift.modulemap";
- MTL_ENABLE_DEBUG_INFO = YES;
OTHER_LDFLAGS = "";
OTHER_LIBTOOLFLAGS = "";
PODS_ROOT = "$(SRCROOT)";
@@ -507,107 +518,112 @@
SKIP_INSTALL = YES;
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
- SWIFT_VERSION = 3.0;
TARGETED_DEVICE_FAMILY = "1,2";
VERSIONING_SYSTEM = "apple-generic";
VERSION_INFO_PREFIX = "";
};
name = Debug;
};
- B693A57C53A73E642AA38054EA7FA303 /* Release */ = {
- isa = XCBuildConfiguration;
- baseConfigurationReference = 077D151C882C36797498299FA868DD45 /* Pods-WRNavigationBar_swift.release.xcconfig */;
- buildSettings = {
- CODE_SIGN_IDENTITY = "";
- "CODE_SIGN_IDENTITY[sdk=appletvos*]" = "";
- "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "";
- "CODE_SIGN_IDENTITY[sdk=watchos*]" = "";
- CURRENT_PROJECT_VERSION = 1;
- DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
- DEFINES_MODULE = YES;
- DYLIB_COMPATIBILITY_VERSION = 1;
- DYLIB_CURRENT_VERSION = 1;
- DYLIB_INSTALL_NAME_BASE = "@rpath";
- ENABLE_STRICT_OBJC_MSGSEND = YES;
- GCC_NO_COMMON_BLOCKS = YES;
- INFOPLIST_FILE = "Target Support Files/Pods-WRNavigationBar_swift/Info.plist";
- INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
- IPHONEOS_DEPLOYMENT_TARGET = 8.0;
- LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
- MACH_O_TYPE = staticlib;
- MODULEMAP_FILE = "Target Support Files/Pods-WRNavigationBar_swift/Pods-WRNavigationBar_swift.modulemap";
- MTL_ENABLE_DEBUG_INFO = NO;
- OTHER_LDFLAGS = "";
- OTHER_LIBTOOLFLAGS = "";
- PODS_ROOT = "$(SRCROOT)";
- PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}";
- PRODUCT_NAME = Pods_WRNavigationBar_swift;
- SDKROOT = iphoneos;
- SKIP_INSTALL = YES;
- SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
- SWIFT_VERSION = 3.0;
- TARGETED_DEVICE_FAMILY = "1,2";
- VERSIONING_SYSTEM = "apple-generic";
- VERSION_INFO_PREFIX = "";
- };
- name = Release;
- };
- C104F7F091290C3D1E248192F07FE689 /* Debug */ = {
+ E4B68EE12B21C47CB798D9B1ECA6D7A7 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
- CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES;
- CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
+ CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
- CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES;
+ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
- CLANG_WARN_OBJC_ROOT_CLASS = YES;
+ CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+ CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+ CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
+ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
CODE_SIGNING_REQUIRED = NO;
COPY_PHASE_STRIP = NO;
+ DEBUG_INFORMATION_FORMAT = dwarf;
+ ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
- GCC_C_LANGUAGE_STANDARD = gnu99;
+ GCC_C_LANGUAGE_STANDARD = gnu11;
GCC_DYNAMIC_NO_PIC = NO;
+ GCC_NO_COMMON_BLOCKS = YES;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = (
"POD_CONFIGURATION_DEBUG=1",
"DEBUG=1",
"$(inherited)",
);
- GCC_SYMBOLS_PRIVATE_EXTERN = NO;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
- GCC_WARN_ABOUT_RETURN_TYPE = YES;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
- GCC_WARN_UNINITIALIZED_AUTOS = YES;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
+ MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES;
+ PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = NO_SIGNING/;
STRIP_INSTALLED_PRODUCT = NO;
+ SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
SYMROOT = "${SRCROOT}/../build";
};
name = Debug;
};
+ E8652F35BF322A3957D0F62338910B79 /* Release */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = 52DC30D7E6C1223D54467216A97B0B7D /* Kingfisher.xcconfig */;
+ buildSettings = {
+ CODE_SIGN_IDENTITY = "";
+ "CODE_SIGN_IDENTITY[sdk=appletvos*]" = "";
+ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "";
+ "CODE_SIGN_IDENTITY[sdk=watchos*]" = "";
+ CURRENT_PROJECT_VERSION = 1;
+ DEFINES_MODULE = YES;
+ DYLIB_COMPATIBILITY_VERSION = 1;
+ DYLIB_CURRENT_VERSION = 1;
+ DYLIB_INSTALL_NAME_BASE = "@rpath";
+ GCC_PREFIX_HEADER = "Target Support Files/Kingfisher/Kingfisher-prefix.pch";
+ INFOPLIST_FILE = "Target Support Files/Kingfisher/Info.plist";
+ INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
+ IPHONEOS_DEPLOYMENT_TARGET = 8.0;
+ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
+ MODULEMAP_FILE = "Target Support Files/Kingfisher/Kingfisher.modulemap";
+ PRODUCT_NAME = Kingfisher;
+ SDKROOT = iphoneos;
+ SKIP_INSTALL = YES;
+ SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) ";
+ SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
+ SWIFT_VERSION = 4.0;
+ TARGETED_DEVICE_FAMILY = "1,2";
+ VALIDATE_PRODUCT = YES;
+ VERSIONING_SYSTEM = "apple-generic";
+ VERSION_INFO_PREFIX = "";
+ };
+ name = Release;
+ };
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
2D8E8EC45A3A1A1D94AE762CB5028504 /* Build configuration list for PBXProject "Pods" */ = {
isa = XCConfigurationList;
buildConfigurations = (
- C104F7F091290C3D1E248192F07FE689 /* Debug */,
- 34FE9531DA9AF2820790339988D5FF41 /* Release */,
+ E4B68EE12B21C47CB798D9B1ECA6D7A7 /* Debug */,
+ B254DAA6CF0CE39F4A3D11B90A7E059A /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
@@ -615,17 +631,17 @@
3BC883AEA3BFFB398C35E6F6E3F9689C /* Build configuration list for PBXNativeTarget "Pods-WRNavigationBar_swift" */ = {
isa = XCConfigurationList;
buildConfigurations = (
- B1AC7D6C94B5F6C383D0C0DF11F6AE13 /* Debug */,
- B693A57C53A73E642AA38054EA7FA303 /* Release */,
+ B44E7915DC09BA8049ACD6E6966BF9CC /* Debug */,
+ 961384A12D2CE6B1C90AD0CABD2F3B67 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
- 76E7EFBCEA1340954A03AA68051C2306 /* Build configuration list for PBXNativeTarget "Kingfisher" */ = {
+ 8C1E4CEFB2390CBE75E70BAC20F44BBF /* Build configuration list for PBXNativeTarget "Kingfisher" */ = {
isa = XCConfigurationList;
buildConfigurations = (
- A794525992F2457D34942D108D9E942A /* Debug */,
- 20B5F4B4605A7E04AEE71183A359E092 /* Release */,
+ 576C583E88A92DC2279EB3BFC2CA8A6C /* Debug */,
+ E8652F35BF322A3957D0F62338910B79 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
diff --git a/WRNavigationBar_swift/Pods/Target Support Files/Kingfisher/Info.plist b/WRNavigationBar_swift/Pods/Target Support Files/Kingfisher/Info.plist
index f4b9ea8..33563de 100644
--- a/WRNavigationBar_swift/Pods/Target Support Files/Kingfisher/Info.plist
+++ b/WRNavigationBar_swift/Pods/Target Support Files/Kingfisher/Info.plist
@@ -15,7 +15,7 @@
CFBundlePackageType
FMWK
CFBundleShortVersionString
- 3.6.2
+ 4.3.1
CFBundleSignature
????
CFBundleVersion
diff --git a/WRNavigationBar_swift/Pods/Target Support Files/Kingfisher/Kingfisher.xcconfig b/WRNavigationBar_swift/Pods/Target Support Files/Kingfisher/Kingfisher.xcconfig
index 6e8fd9e..e05e95c 100644
--- a/WRNavigationBar_swift/Pods/Target Support Files/Kingfisher/Kingfisher.xcconfig
+++ b/WRNavigationBar_swift/Pods/Target Support Files/Kingfisher/Kingfisher.xcconfig
@@ -9,4 +9,4 @@ PODS_ROOT = ${SRCROOT}
PODS_TARGET_SRCROOT = ${PODS_ROOT}/Kingfisher
PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier}
SKIP_INSTALL = YES
-SWIFT_VERSION = 3.0
+SWIFT_VERSION = 4.0
diff --git a/WRNavigationBar_swift/Pods/Target Support Files/Pods-WRNavigationBar_swift/Pods-WRNavigationBar_swift-frameworks.sh b/WRNavigationBar_swift/Pods/Target Support Files/Pods-WRNavigationBar_swift/Pods-WRNavigationBar_swift-frameworks.sh
index b1c3c96..82bcb19 100755
--- a/WRNavigationBar_swift/Pods/Target Support Files/Pods-WRNavigationBar_swift/Pods-WRNavigationBar_swift-frameworks.sh
+++ b/WRNavigationBar_swift/Pods/Target Support Files/Pods-WRNavigationBar_swift/Pods-WRNavigationBar_swift-frameworks.sh
@@ -6,6 +6,10 @@ mkdir -p "${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
SWIFT_STDLIB_PATH="${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}"
+# This protects against multiple targets copying the same framework dependency at the same time. The solution
+# was originally proposed here: https://lists.samba.org/archive/rsync/2008-February/020158.html
+RSYNC_PROTECT_TMP_FILES=(--filter "P .*.??????")
+
install_framework()
{
if [ -r "${BUILT_PRODUCTS_DIR}/$1" ]; then
@@ -23,9 +27,9 @@ install_framework()
source="$(readlink "${source}")"
fi
- # use filter instead of exclude so missing patterns dont' throw errors
- echo "rsync -av --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${destination}\""
- rsync -av --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${destination}"
+ # Use filter instead of exclude so missing patterns don't throw errors.
+ echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${destination}\""
+ rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${destination}"
local basename
basename="$(basename -s .framework "$1")"
@@ -54,6 +58,15 @@ install_framework()
fi
}
+# Copies the dSYM of a vendored framework
+install_dsym() {
+ local source="$1"
+ if [ -r "$source" ]; then
+ echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${DWARF_DSYM_FOLDER_PATH}\""
+ rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${DWARF_DSYM_FOLDER_PATH}"
+ fi
+}
+
# Signs a framework with the provided identity
code_sign_if_enabled() {
if [ -n "${EXPANDED_CODE_SIGN_IDENTITY}" -a "${CODE_SIGNING_REQUIRED}" != "NO" -a "${CODE_SIGNING_ALLOWED}" != "NO" ]; then
@@ -76,7 +89,7 @@ strip_invalid_archs() {
archs="$(lipo -info "$binary" | rev | cut -d ':' -f1 | rev)"
stripped=""
for arch in $archs; do
- if ! [[ "${VALID_ARCHS}" == *"$arch"* ]]; then
+ if ! [[ "${ARCHS}" == *"$arch"* ]]; then
# Strip non-valid architectures in-place
lipo -remove "$arch" -output "$binary" "$binary" || exit 1
stripped="$stripped $arch"
@@ -89,10 +102,10 @@ strip_invalid_archs() {
if [[ "$CONFIGURATION" == "Debug" ]]; then
- install_framework "$BUILT_PRODUCTS_DIR/Kingfisher/Kingfisher.framework"
+ install_framework "${BUILT_PRODUCTS_DIR}/Kingfisher/Kingfisher.framework"
fi
if [[ "$CONFIGURATION" == "Release" ]]; then
- install_framework "$BUILT_PRODUCTS_DIR/Kingfisher/Kingfisher.framework"
+ install_framework "${BUILT_PRODUCTS_DIR}/Kingfisher/Kingfisher.framework"
fi
if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then
wait
diff --git a/WRNavigationBar_swift/Pods/Target Support Files/Pods-WRNavigationBar_swift/Pods-WRNavigationBar_swift-resources.sh b/WRNavigationBar_swift/Pods/Target Support Files/Pods-WRNavigationBar_swift/Pods-WRNavigationBar_swift-resources.sh
index aed060f..a7df440 100755
--- a/WRNavigationBar_swift/Pods/Target Support Files/Pods-WRNavigationBar_swift/Pods-WRNavigationBar_swift-resources.sh
+++ b/WRNavigationBar_swift/Pods/Target Support Files/Pods-WRNavigationBar_swift/Pods-WRNavigationBar_swift-resources.sh
@@ -8,6 +8,10 @@ RESOURCES_TO_COPY=${PODS_ROOT}/resources-to-copy-${TARGETNAME}.txt
XCASSET_FILES=()
+# This protects against multiple targets copying the same framework dependency at the same time. The solution
+# was originally proposed here: https://lists.samba.org/archive/rsync/2008-February/020158.html
+RSYNC_PROTECT_TMP_FILES=(--filter "P .*.??????")
+
case "${TARGETED_DEVICE_FAMILY}" in
1,2)
TARGET_DEVICE_ARGS="--target-device ipad --target-device iphone"
@@ -44,29 +48,29 @@ EOM
fi
case $RESOURCE_PATH in
*.storyboard)
- echo "ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile ${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .storyboard`.storyboardc $RESOURCE_PATH --sdk ${SDKROOT} ${TARGET_DEVICE_ARGS}"
+ echo "ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile ${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .storyboard`.storyboardc $RESOURCE_PATH --sdk ${SDKROOT} ${TARGET_DEVICE_ARGS}" || true
ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .storyboard`.storyboardc" "$RESOURCE_PATH" --sdk "${SDKROOT}" ${TARGET_DEVICE_ARGS}
;;
*.xib)
- echo "ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile ${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .xib`.nib $RESOURCE_PATH --sdk ${SDKROOT} ${TARGET_DEVICE_ARGS}"
+ echo "ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile ${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .xib`.nib $RESOURCE_PATH --sdk ${SDKROOT} ${TARGET_DEVICE_ARGS}" || true
ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .xib`.nib" "$RESOURCE_PATH" --sdk "${SDKROOT}" ${TARGET_DEVICE_ARGS}
;;
*.framework)
- echo "mkdir -p ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
+ echo "mkdir -p ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" || true
mkdir -p "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
- echo "rsync -av $RESOURCE_PATH ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
- rsync -av "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
+ echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" $RESOURCE_PATH ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" || true
+ rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
;;
*.xcdatamodel)
- echo "xcrun momc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH"`.mom\""
+ echo "xcrun momc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH"`.mom\"" || true
xcrun momc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodel`.mom"
;;
*.xcdatamodeld)
- echo "xcrun momc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodeld`.momd\""
+ echo "xcrun momc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodeld`.momd\"" || true
xcrun momc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodeld`.momd"
;;
*.xcmappingmodel)
- echo "xcrun mapc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcmappingmodel`.cdm\""
+ echo "xcrun mapc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcmappingmodel`.cdm\"" || true
xcrun mapc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcmappingmodel`.cdm"
;;
*.xcassets)
@@ -74,7 +78,7 @@ EOM
XCASSET_FILES+=("$ABSOLUTE_XCASSET_FILE")
;;
*)
- echo "$RESOURCE_PATH"
+ echo "$RESOURCE_PATH" || true
echo "$RESOURCE_PATH" >> "$RESOURCES_TO_COPY"
;;
esac
diff --git a/WRNavigationBar_swift/WRNavigationBar_swift.xcodeproj/project.pbxproj b/WRNavigationBar_swift/WRNavigationBar_swift.xcodeproj/project.pbxproj
index 15e7de6..f37db52 100644
--- a/WRNavigationBar_swift/WRNavigationBar_swift.xcodeproj/project.pbxproj
+++ b/WRNavigationBar_swift/WRNavigationBar_swift.xcodeproj/project.pbxproj
@@ -7,23 +7,25 @@
objects = {
/* Begin PBXBuildFile section */
+ 1A05B4741F07FA9C001D7B64 /* WRNavigationBar.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1A05B4731F07FA9C001D7B64 /* WRNavigationBar.swift */; };
+ 1A05B4761F07FAB4001D7B64 /* NormalListController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1A05B4751F07FAB4001D7B64 /* NormalListController.swift */; };
+ 1A05B4781F07FAD7001D7B64 /* ImageNavController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1A05B4771F07FAD7001D7B64 /* ImageNavController.swift */; };
+ 1A05B47A1F080D0B001D7B64 /* MillcolorGradController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1A05B4791F080D0B001D7B64 /* MillcolorGradController.swift */; };
1A0DF77B1EA7176500191349 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1A0DF77A1EA7176500191349 /* AppDelegate.swift */; };
1A0DF7801EA7176500191349 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 1A0DF77E1EA7176500191349 /* Main.storyboard */; };
1A0DF7821EA7176500191349 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 1A0DF7811EA7176500191349 /* Assets.xcassets */; };
1A0DF7851EA7176500191349 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 1A0DF7831EA7176500191349 /* LaunchScreen.storyboard */; };
1A0DF7901EA7176500191349 /* WRNavigationBar_swiftTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1A0DF78F1EA7176500191349 /* WRNavigationBar_swiftTests.swift */; };
- 1A0DF7B31EA7372800191349 /* NormalListController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1A0DF7B21EA7372800191349 /* NormalListController.swift */; };
1A0DF7B51EA7380600191349 /* SixthViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1A0DF7B41EA7380600191349 /* SixthViewController.swift */; };
1A0DF7B71EA7471B00191349 /* WeiBoMineController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1A0DF7B61EA7471B00191349 /* WeiBoMineController.swift */; };
1A0DF7B91EA7521C00191349 /* BaseNavigationController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1A0DF7B81EA7521C00191349 /* BaseNavigationController.swift */; };
- 1A0DF7BE1EA7545900191349 /* WRNavigationBar.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1A0DF7BD1EA7545900191349 /* WRNavigationBar.swift */; };
1A869EDD1ECAA0C1006D96F8 /* BaseViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1A869EDC1ECAA0C1006D96F8 /* BaseViewController.swift */; };
1A869EDF1ECAA36B006D96F8 /* CustomNavBarController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1A869EDE1ECAA36B006D96F8 /* CustomNavBarController.swift */; };
1A96559C1ED6B64F00A89E30 /* CustomListController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1A96559B1ED6B64F00A89E30 /* CustomListController.swift */; };
1A96559E1ED6B8C600A89E30 /* MoveListController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1A96559D1ED6B8C600A89E30 /* MoveListController.swift */; };
1A966E8D1EE048F60045FCB8 /* AntForestController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1A966E8C1EE048F60045FCB8 /* AntForestController.swift */; };
+ 1AADC3941F23088600BB73D9 /* AllTransparent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1AADC3931F23088600BB73D9 /* AllTransparent.swift */; };
1AB702661EA9A43C006DBA79 /* SecondViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1AB702651EA9A43C006DBA79 /* SecondViewController.swift */; };
- 1AB702681EA9A9BC006DBA79 /* ThirdViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1AB702671EA9A9BC006DBA79 /* ThirdViewController.swift */; };
1AB7026A1EA9AC7A006DBA79 /* QQAppController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1AB702691EA9AC7A006DBA79 /* QQAppController.swift */; };
1AB7026C1EA9B753006DBA79 /* QQZoneController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1AB7026B1EA9B753006DBA79 /* QQZoneController.swift */; };
1AD0140A1EDBFB4500A6893C /* ZhiHuController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1AD014091EDBFB4500A6893C /* ZhiHuController.swift */; };
@@ -31,6 +33,7 @@
1AD014101EDBFEAC00A6893C /* WRCycleScrollView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1AD0140D1EDBFEAC00A6893C /* WRCycleScrollView.swift */; };
1AD014111EDBFEAC00A6893C /* WRProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1AD0140E1EDBFEAC00A6893C /* WRProxy.swift */; };
1AD014131EDC091F00A6893C /* QQMineController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1AD014121EDC091F00A6893C /* QQMineController.swift */; };
+ 34A093CA1FC941B0009119BF /* WRCustomNavigationBar.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34A093C91FC941B0009119BF /* WRCustomNavigationBar.swift */; };
BA823A4F29CFCD6EEC3B52B9 /* Pods_WRNavigationBar_swift.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 63C8A182323696F064D8660C /* Pods_WRNavigationBar_swift.framework */; };
/* End PBXBuildFile section */
@@ -45,6 +48,10 @@
/* End PBXContainerItemProxy section */
/* Begin PBXFileReference section */
+ 1A05B4731F07FA9C001D7B64 /* WRNavigationBar.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WRNavigationBar.swift; sourceTree = ""; };
+ 1A05B4751F07FAB4001D7B64 /* NormalListController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NormalListController.swift; sourceTree = ""; };
+ 1A05B4771F07FAD7001D7B64 /* ImageNavController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ImageNavController.swift; sourceTree = ""; };
+ 1A05B4791F080D0B001D7B64 /* MillcolorGradController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MillcolorGradController.swift; sourceTree = ""; };
1A0DF7771EA7176500191349 /* WRNavigationBar_swift.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = WRNavigationBar_swift.app; sourceTree = BUILT_PRODUCTS_DIR; };
1A0DF77A1EA7176500191349 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; };
1A0DF77F1EA7176500191349 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; };
@@ -54,18 +61,16 @@
1A0DF78B1EA7176500191349 /* WRNavigationBar_swiftTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = WRNavigationBar_swiftTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
1A0DF78F1EA7176500191349 /* WRNavigationBar_swiftTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WRNavigationBar_swiftTests.swift; sourceTree = ""; };
1A0DF7911EA7176500191349 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
- 1A0DF7B21EA7372800191349 /* NormalListController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NormalListController.swift; sourceTree = ""; };
1A0DF7B41EA7380600191349 /* SixthViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SixthViewController.swift; sourceTree = ""; };
1A0DF7B61EA7471B00191349 /* WeiBoMineController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WeiBoMineController.swift; sourceTree = ""; };
1A0DF7B81EA7521C00191349 /* BaseNavigationController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = BaseNavigationController.swift; path = Demos/BaseNavigationController.swift; sourceTree = ""; };
- 1A0DF7BD1EA7545900191349 /* WRNavigationBar.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WRNavigationBar.swift; sourceTree = ""; };
1A869EDC1ECAA0C1006D96F8 /* BaseViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BaseViewController.swift; sourceTree = ""; };
1A869EDE1ECAA36B006D96F8 /* CustomNavBarController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CustomNavBarController.swift; sourceTree = ""; };
1A96559B1ED6B64F00A89E30 /* CustomListController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CustomListController.swift; sourceTree = ""; };
1A96559D1ED6B8C600A89E30 /* MoveListController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MoveListController.swift; sourceTree = ""; };
1A966E8C1EE048F60045FCB8 /* AntForestController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AntForestController.swift; sourceTree = ""; };
+ 1AADC3931F23088600BB73D9 /* AllTransparent.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AllTransparent.swift; sourceTree = ""; };
1AB702651EA9A43C006DBA79 /* SecondViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SecondViewController.swift; sourceTree = ""; };
- 1AB702671EA9A9BC006DBA79 /* ThirdViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ThirdViewController.swift; sourceTree = ""; };
1AB702691EA9AC7A006DBA79 /* QQAppController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = QQAppController.swift; sourceTree = ""; };
1AB7026B1EA9B753006DBA79 /* QQZoneController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = QQZoneController.swift; sourceTree = ""; };
1AD014091EDBFB4500A6893C /* ZhiHuController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ZhiHuController.swift; sourceTree = ""; };
@@ -74,6 +79,7 @@
1AD0140E1EDBFEAC00A6893C /* WRProxy.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WRProxy.swift; sourceTree = ""; };
1AD014121EDC091F00A6893C /* QQMineController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = QQMineController.swift; sourceTree = ""; };
272C2A7862DC39DA91D57781 /* Pods-WRNavigationBar_swift.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-WRNavigationBar_swift.release.xcconfig"; path = "Pods/Target Support Files/Pods-WRNavigationBar_swift/Pods-WRNavigationBar_swift.release.xcconfig"; sourceTree = ""; };
+ 34A093C91FC941B0009119BF /* WRCustomNavigationBar.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WRCustomNavigationBar.swift; sourceTree = ""; };
63C8A182323696F064D8660C /* Pods_WRNavigationBar_swift.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_WRNavigationBar_swift.framework; sourceTree = BUILT_PRODUCTS_DIR; };
D76868588A082EB7E7777210 /* Pods-WRNavigationBar_swift.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-WRNavigationBar_swift.debug.xcconfig"; path = "Pods/Target Support Files/Pods-WRNavigationBar_swift/Pods-WRNavigationBar_swift.debug.xcconfig"; sourceTree = ""; };
/* End PBXFileReference section */
@@ -147,7 +153,8 @@
1A0DF79A1EA7179500191349 /* WRNavigationBar */ = {
isa = PBXGroup;
children = (
- 1A0DF7BD1EA7545900191349 /* WRNavigationBar.swift */,
+ 1A05B4731F07FA9C001D7B64 /* WRNavigationBar.swift */,
+ 34A093C91FC941B0009119BF /* WRCustomNavigationBar.swift */,
);
path = WRNavigationBar;
sourceTree = "";
@@ -155,13 +162,14 @@
1A0DF7B11EA7370000191349 /* 普通 */ = {
isa = PBXGroup;
children = (
- 1A0DF7B21EA7372800191349 /* NormalListController.swift */,
+ 1A05B4751F07FAB4001D7B64 /* NormalListController.swift */,
1A0DF7B61EA7471B00191349 /* WeiBoMineController.swift */,
1AB702691EA9AC7A006DBA79 /* QQAppController.swift */,
1AB7026B1EA9B753006DBA79 /* QQZoneController.swift */,
1AD014091EDBFB4500A6893C /* ZhiHuController.swift */,
1AD014121EDC091F00A6893C /* QQMineController.swift */,
1A966E8C1EE048F60045FCB8 /* AntForestController.swift */,
+ 1AADC3931F23088600BB73D9 /* AllTransparent.swift */,
);
name = "普通";
path = Demos;
@@ -173,6 +181,8 @@
1A869EDC1ECAA0C1006D96F8 /* BaseViewController.swift */,
1A96559B1ED6B64F00A89E30 /* CustomListController.swift */,
1A869EDE1ECAA36B006D96F8 /* CustomNavBarController.swift */,
+ 1A05B4771F07FAD7001D7B64 /* ImageNavController.swift */,
+ 1A05B4791F080D0B001D7B64 /* MillcolorGradController.swift */,
);
name = "自定义导航栏";
path = Demos;
@@ -183,7 +193,6 @@
children = (
1A96559D1ED6B8C600A89E30 /* MoveListController.swift */,
1AB702651EA9A43C006DBA79 /* SecondViewController.swift */,
- 1AB702671EA9A9BC006DBA79 /* ThirdViewController.swift */,
1A0DF7B41EA7380600191349 /* SixthViewController.swift */,
);
name = "移动导航栏";
@@ -266,17 +275,19 @@
isa = PBXProject;
attributes = {
LastSwiftUpdateCheck = 0810;
- LastUpgradeCheck = 0810;
+ LastUpgradeCheck = 0900;
ORGANIZATIONNAME = wangrui;
TargetAttributes = {
1A0DF7761EA7176500191349 = {
CreatedOnToolsVersion = 8.1;
DevelopmentTeam = 652U6LDTX4;
+ LastSwiftMigration = 0900;
ProvisioningStyle = Automatic;
};
1A0DF78A1EA7176500191349 = {
CreatedOnToolsVersion = 8.1;
DevelopmentTeam = 652U6LDTX4;
+ LastSwiftMigration = 0900;
ProvisioningStyle = Automatic;
TestTargetID = 1A0DF7761EA7176500191349;
};
@@ -343,13 +354,16 @@
files = (
);
inputPaths = (
+ "${PODS_PODFILE_DIR_PATH}/Podfile.lock",
+ "${PODS_ROOT}/Manifest.lock",
);
name = "[CP] Check Pods Manifest.lock";
outputPaths = (
+ "$(DERIVED_FILE_DIR)/Pods-WRNavigationBar_swift-checkManifestLockResult.txt",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
- shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n";
+ shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
showEnvVarsInLog = 0;
};
D52EBFEB66FB9C860C432F23 /* [CP] Embed Pods Frameworks */ = {
@@ -358,9 +372,12 @@
files = (
);
inputPaths = (
+ "${SRCROOT}/Pods/Target Support Files/Pods-WRNavigationBar_swift/Pods-WRNavigationBar_swift-frameworks.sh",
+ "${BUILT_PRODUCTS_DIR}/Kingfisher/Kingfisher.framework",
);
name = "[CP] Embed Pods Frameworks";
outputPaths = (
+ "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Kingfisher.framework",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
@@ -377,13 +394,16 @@
1A869EDF1ECAA36B006D96F8 /* CustomNavBarController.swift in Sources */,
1AD014131EDC091F00A6893C /* QQMineController.swift in Sources */,
1AB7026C1EA9B753006DBA79 /* QQZoneController.swift in Sources */,
+ 1A05B47A1F080D0B001D7B64 /* MillcolorGradController.swift in Sources */,
+ 1A05B4781F07FAD7001D7B64 /* ImageNavController.swift in Sources */,
1A96559E1ED6B8C600A89E30 /* MoveListController.swift in Sources */,
1AD014111EDBFEAC00A6893C /* WRProxy.swift in Sources */,
- 1A0DF7BE1EA7545900191349 /* WRNavigationBar.swift in Sources */,
1AD0140A1EDBFB4500A6893C /* ZhiHuController.swift in Sources */,
1AD0140F1EDBFEAC00A6893C /* WRCycleCell.swift in Sources */,
+ 34A093CA1FC941B0009119BF /* WRCustomNavigationBar.swift in Sources */,
1A869EDD1ECAA0C1006D96F8 /* BaseViewController.swift in Sources */,
- 1A0DF7B31EA7372800191349 /* NormalListController.swift in Sources */,
+ 1A05B4761F07FAB4001D7B64 /* NormalListController.swift in Sources */,
+ 1A05B4741F07FA9C001D7B64 /* WRNavigationBar.swift in Sources */,
1AD014101EDBFEAC00A6893C /* WRCycleScrollView.swift in Sources */,
1A0DF7B51EA7380600191349 /* SixthViewController.swift in Sources */,
1AB7026A1EA9AC7A006DBA79 /* QQAppController.swift in Sources */,
@@ -392,7 +412,7 @@
1A96559C1ED6B64F00A89E30 /* CustomListController.swift in Sources */,
1AB702661EA9A43C006DBA79 /* SecondViewController.swift in Sources */,
1A0DF7B91EA7521C00191349 /* BaseNavigationController.swift in Sources */,
- 1AB702681EA9A9BC006DBA79 /* ThirdViewController.swift in Sources */,
+ 1AADC3941F23088600BB73D9 /* AllTransparent.swift in Sources */,
1A0DF7B71EA7471B00191349 /* WeiBoMineController.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
@@ -444,7 +464,9 @@
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
@@ -452,7 +474,12 @@
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+ CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+ CLANG_WARN_STRICT_PROTOTYPES = YES;
+ CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_SUSPICIOUS_MOVES = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
@@ -494,7 +521,9 @@
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
@@ -502,7 +531,12 @@
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+ CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+ CLANG_WARN_STRICT_PROTOTYPES = YES;
+ CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_SUSPICIOUS_MOVES = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
@@ -537,9 +571,10 @@
INFOPLIST_FILE = WRNavigationBar_swift/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
- PRODUCT_BUNDLE_IDENTIFIER = "video.wangrui.com.WRNavigationBar-swift";
+ PRODUCT_BUNDLE_IDENTIFIER = video.com.wangrui;
PRODUCT_NAME = "$(TARGET_NAME)";
- SWIFT_VERSION = 3.0;
+ SWIFT_SWIFT3_OBJC_INFERENCE = Default;
+ SWIFT_VERSION = 4.0;
TARGETED_DEVICE_FAMILY = 1;
};
name = Debug;
@@ -553,9 +588,10 @@
INFOPLIST_FILE = WRNavigationBar_swift/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
- PRODUCT_BUNDLE_IDENTIFIER = "video.wangrui.com.WRNavigationBar-swift";
+ PRODUCT_BUNDLE_IDENTIFIER = video.com.wangrui;
PRODUCT_NAME = "$(TARGET_NAME)";
- SWIFT_VERSION = 3.0;
+ SWIFT_SWIFT3_OBJC_INFERENCE = Default;
+ SWIFT_VERSION = 4.0;
TARGETED_DEVICE_FAMILY = 1;
};
name = Release;
@@ -570,7 +606,8 @@
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = "video.wangrui.com.WRNavigationBar-swiftTests";
PRODUCT_NAME = "$(TARGET_NAME)";
- SWIFT_VERSION = 3.0;
+ SWIFT_SWIFT3_OBJC_INFERENCE = On;
+ SWIFT_VERSION = 4.0;
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/WRNavigationBar_swift.app/WRNavigationBar_swift";
};
name = Debug;
@@ -585,7 +622,8 @@
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = "video.wangrui.com.WRNavigationBar-swiftTests";
PRODUCT_NAME = "$(TARGET_NAME)";
- SWIFT_VERSION = 3.0;
+ SWIFT_SWIFT3_OBJC_INFERENCE = On;
+ SWIFT_VERSION = 4.0;
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/WRNavigationBar_swift.app/WRNavigationBar_swift";
};
name = Release;
diff --git a/WRNavigationBar_swift/WRNavigationBar_swift/AppDelegate.swift b/WRNavigationBar_swift/WRNavigationBar_swift/AppDelegate.swift
index cfa6f8e..3928939 100644
--- a/WRNavigationBar_swift/WRNavigationBar_swift/AppDelegate.swift
+++ b/WRNavigationBar_swift/WRNavigationBar_swift/AppDelegate.swift
@@ -59,13 +59,15 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
func setNavBarAppearence()
{
// 设置导航栏默认的背景颜色
- UIColor.defaultNavBarBarTintColor = UIColor.init(red: 0/255.0, green: 175/255.0, blue: 240/255.0, alpha: 1)
+ WRNavigationBar.defaultNavBarBarTintColor = UIColor.init(red: 0/255.0, green: 175/255.0, blue: 240/255.0, alpha: 1)
// 设置导航栏所有按钮的默认颜色
- UIColor.defaultNavBarTintColor = .white
+ WRNavigationBar.defaultNavBarTintColor = .white
// 设置导航栏标题默认颜色
- UIColor.defaultNavBarTitleColor = .white
+ WRNavigationBar.defaultNavBarTitleColor = .white
// 统一设置状态栏样式
- UIColor.defaultStatusBarStyle = .lightContent
+ WRNavigationBar.defaultStatusBarStyle = .lightContent
+ // 如果需要设置导航栏底部分割线隐藏,可以在这里统一设置
+ WRNavigationBar.defaultShadowImageHidden = true
}
}
diff --git a/WRNavigationBar_swift/WRNavigationBar_swift/Assets.xcassets/AppIcon.appiconset/Contents.json b/WRNavigationBar_swift/WRNavigationBar_swift/Assets.xcassets/AppIcon.appiconset/Contents.json
index a954173..440402b 100644
--- a/WRNavigationBar_swift/WRNavigationBar_swift/Assets.xcassets/AppIcon.appiconset/Contents.json
+++ b/WRNavigationBar_swift/WRNavigationBar_swift/Assets.xcassets/AppIcon.appiconset/Contents.json
@@ -41,6 +41,11 @@
"idiom" : "iphone",
"filename" : "180wr.png",
"scale" : "3x"
+ },
+ {
+ "idiom" : "ios-marketing",
+ "size" : "1024x1024",
+ "scale" : "1x"
}
],
"info" : {
diff --git a/WRNavigationBar_swift/WRNavigationBar_swift/Assets.xcassets/image7.imageset/Contents.json b/WRNavigationBar_swift/WRNavigationBar_swift/Assets.xcassets/image7.imageset/Contents.json
new file mode 100644
index 0000000..2f0fafd
--- /dev/null
+++ b/WRNavigationBar_swift/WRNavigationBar_swift/Assets.xcassets/image7.imageset/Contents.json
@@ -0,0 +1,21 @@
+{
+ "images" : [
+ {
+ "idiom" : "universal",
+ "filename" : "u=2864424897,2473674229&fm=26&gp=0.jpg",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "universal",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "universal",
+ "scale" : "3x"
+ }
+ ],
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ }
+}
\ No newline at end of file
diff --git a/WRNavigationBar_swift/WRNavigationBar_swift/Assets.xcassets/image7.imageset/u=2864424897,2473674229&fm=26&gp=0.jpg b/WRNavigationBar_swift/WRNavigationBar_swift/Assets.xcassets/image7.imageset/u=2864424897,2473674229&fm=26&gp=0.jpg
new file mode 100644
index 0000000..bb033b5
Binary files /dev/null and b/WRNavigationBar_swift/WRNavigationBar_swift/Assets.xcassets/image7.imageset/u=2864424897,2473674229&fm=26&gp=0.jpg differ
diff --git a/WRNavigationBar_swift/WRNavigationBar_swift/Assets.xcassets/image8.imageset/Contents.json b/WRNavigationBar_swift/WRNavigationBar_swift/Assets.xcassets/image8.imageset/Contents.json
new file mode 100644
index 0000000..3113f50
--- /dev/null
+++ b/WRNavigationBar_swift/WRNavigationBar_swift/Assets.xcassets/image8.imageset/Contents.json
@@ -0,0 +1,21 @@
+{
+ "images" : [
+ {
+ "idiom" : "universal",
+ "filename" : "cad334853a19ab63f278ed8532ff8ae1.jpeg",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "universal",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "universal",
+ "scale" : "3x"
+ }
+ ],
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ }
+}
\ No newline at end of file
diff --git a/WRNavigationBar_swift/WRNavigationBar_swift/Assets.xcassets/image8.imageset/cad334853a19ab63f278ed8532ff8ae1.jpeg b/WRNavigationBar_swift/WRNavigationBar_swift/Assets.xcassets/image8.imageset/cad334853a19ab63f278ed8532ff8ae1.jpeg
new file mode 100644
index 0000000..d2e2e85
Binary files /dev/null and b/WRNavigationBar_swift/WRNavigationBar_swift/Assets.xcassets/image8.imageset/cad334853a19ab63f278ed8532ff8ae1.jpeg differ
diff --git a/WRNavigationBar_swift/WRNavigationBar_swift/Assets.xcassets/imageNav.imageset/Contents.json b/WRNavigationBar_swift/WRNavigationBar_swift/Assets.xcassets/imageNav.imageset/Contents.json
new file mode 100644
index 0000000..47c7b4b
--- /dev/null
+++ b/WRNavigationBar_swift/WRNavigationBar_swift/Assets.xcassets/imageNav.imageset/Contents.json
@@ -0,0 +1,21 @@
+{
+ "images" : [
+ {
+ "idiom" : "universal",
+ "filename" : "u=1206318416,27195661&fm=26&gp=0.jpg",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "universal",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "universal",
+ "scale" : "3x"
+ }
+ ],
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ }
+}
\ No newline at end of file
diff --git a/WRNavigationBar_swift/WRNavigationBar_swift/Assets.xcassets/imageNav.imageset/u=1206318416,27195661&fm=26&gp=0.jpg b/WRNavigationBar_swift/WRNavigationBar_swift/Assets.xcassets/imageNav.imageset/u=1206318416,27195661&fm=26&gp=0.jpg
new file mode 100644
index 0000000..49bf221
Binary files /dev/null and b/WRNavigationBar_swift/WRNavigationBar_swift/Assets.xcassets/imageNav.imageset/u=1206318416,27195661&fm=26&gp=0.jpg differ
diff --git a/WRNavigationBar_swift/WRNavigationBar_swift/Assets.xcassets/millcolorGrad.imageset/Contents.json b/WRNavigationBar_swift/WRNavigationBar_swift/Assets.xcassets/millcolorGrad.imageset/Contents.json
new file mode 100644
index 0000000..ea26b9f
--- /dev/null
+++ b/WRNavigationBar_swift/WRNavigationBar_swift/Assets.xcassets/millcolorGrad.imageset/Contents.json
@@ -0,0 +1,21 @@
+{
+ "images" : [
+ {
+ "idiom" : "universal",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "universal",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "universal",
+ "filename" : "millcolorGrad.png",
+ "scale" : "3x"
+ }
+ ],
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ }
+}
\ No newline at end of file
diff --git a/WRNavigationBar_swift/WRNavigationBar_swift/Assets.xcassets/millcolorGrad.imageset/millcolorGrad.png b/WRNavigationBar_swift/WRNavigationBar_swift/Assets.xcassets/millcolorGrad.imageset/millcolorGrad.png
new file mode 100644
index 0000000..ab99e3c
Binary files /dev/null and b/WRNavigationBar_swift/WRNavigationBar_swift/Assets.xcassets/millcolorGrad.imageset/millcolorGrad.png differ
diff --git a/WRNavigationBar_swift/WRNavigationBar_swift/Demos/AllTransparent.swift b/WRNavigationBar_swift/WRNavigationBar_swift/Demos/AllTransparent.swift
new file mode 100644
index 0000000..bb73ab7
--- /dev/null
+++ b/WRNavigationBar_swift/WRNavigationBar_swift/Demos/AllTransparent.swift
@@ -0,0 +1,107 @@
+//
+// WeiBoMineController.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
+
+private let IMAGE_HEIGHT:CGFloat = 220
+private let NAVBAR_COLORCHANGE_POINT:CGFloat = IMAGE_HEIGHT - CGFloat(kNavBarBottom * 2)
+
+class AllTransparent: UIViewController
+{
+ lazy var tableView:UITableView = {
+ let table:UITableView = UITableView(frame: CGRect.init(x: 0, y: 0, width: kScreenWidth, height: self.view.bounds.height), style: .plain)
+ table.contentInset = UIEdgeInsetsMake(-CGFloat(kNavBarBottom), 0, 0, 0);
+ table.delegate = self
+ table.dataSource = self
+ return table
+ }()
+ lazy var topView:UIImageView = {
+ let imgView = UIImageView(image: UIImage(named: "wbBg"))
+ imgView.frame = CGRect(x: 0, y: 0, width: kScreenWidth, height: IMAGE_HEIGHT)
+ imgView.contentMode = UIViewContentMode.scaleAspectFill
+ imgView.clipsToBounds = true
+ return imgView
+ }()
+
+ override func viewDidLoad()
+ {
+ super.viewDidLoad()
+ title = "wangrui460"
+ view.backgroundColor = UIColor.red
+ view.addSubview(tableView)
+ tableView.tableHeaderView = topView
+ navigationItem.rightBarButtonItem = UIBarButtonItem(title: "··· ", style: .done, target: nil, action: nil)
+
+ // 设置导航栏颜色
+ navBarBarTintColor = UIColor.init(red: 247/255.0, green: 247/255.0, blue: 247/255.0, alpha: 1.0)
+
+ // 设置初始导航栏透明度
+ navBarBackgroundAlpha = 0
+
+ // 设置导航栏按钮和标题颜色
+ navBarTintColor = .white
+
+ // 如果需要隐藏导航栏底部分割线,设置 hideShadowImage 为true
+ // hideShadowImage = true
+ }
+
+ deinit {
+ tableView.delegate = nil
+ print("FirstVC deinit")
+ }
+}
+
+
+// MARK: - 滑动改变导航栏透明度、标题颜色、左右按钮颜色、状态栏颜色
+extension AllTransparent
+{
+ func scrollViewDidScroll(_ scrollView: UIScrollView)
+ {
+ let offsetY = scrollView.contentOffset.y
+ if (offsetY > NAVBAR_COLORCHANGE_POINT)
+ {
+ let alpha = (offsetY - NAVBAR_COLORCHANGE_POINT) / CGFloat(kNavBarBottom)
+ navBarBackgroundAlpha = alpha
+ navBarTintColor = UIColor.black.withAlphaComponent(alpha)
+ navBarTitleColor = UIColor.black.withAlphaComponent(alpha)
+ statusBarStyle = .default
+ }
+ else
+ {
+ navBarBackgroundAlpha = 0
+ navBarTintColor = .white
+ navBarTitleColor = .white
+ statusBarStyle = .lightContent
+ }
+ }
+}
+
+
+extension AllTransparent:UITableViewDelegate,UITableViewDataSource
+{
+ func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
+ return 40
+ }
+
+ func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
+ {
+ let cell = UITableViewCell.init(style: .default, reuseIdentifier: nil)
+ let str = String(format: "WRNavigationBar %zd", indexPath.row)
+ cell.textLabel?.text = str
+ cell.textLabel?.font = UIFont.systemFont(ofSize: 15)
+ return cell
+ }
+
+ func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)
+ {
+ tableView.deselectRow(at: indexPath, animated: true)
+ let vc:AllTransparent = AllTransparent()
+ navigationController?.pushViewController(vc, animated: true)
+ }
+}
diff --git a/WRNavigationBar_swift/WRNavigationBar_swift/Demos/AntForestController.swift b/WRNavigationBar_swift/WRNavigationBar_swift/Demos/AntForestController.swift
index 4f70dc6..0299261 100644
--- a/WRNavigationBar_swift/WRNavigationBar_swift/Demos/AntForestController.swift
+++ b/WRNavigationBar_swift/WRNavigationBar_swift/Demos/AntForestController.swift
@@ -101,7 +101,7 @@ extension AntForestController
extension AntForestController: UITableViewDelegate,UITableViewDataSource
{
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
- return 15
+ return 25
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
diff --git a/WRNavigationBar_swift/WRNavigationBar_swift/Demos/BaseViewController.swift b/WRNavigationBar_swift/WRNavigationBar_swift/Demos/BaseViewController.swift
index e4edb40..d00029b 100644
--- a/WRNavigationBar_swift/WRNavigationBar_swift/Demos/BaseViewController.swift
+++ b/WRNavigationBar_swift/WRNavigationBar_swift/Demos/BaseViewController.swift
@@ -11,8 +11,7 @@ import UIKit
class BaseViewController: UIViewController
{
- lazy var navBar = UINavigationBar(frame: CGRect(x: 0, y: 0, width: kScreenWidth, height: 64))
- lazy var navItem = UINavigationItem()
+ lazy var navBar = WRCustomNavigationBar.CustomNavigationBar()
override func viewDidLoad()
{
@@ -25,16 +24,28 @@ class BaseViewController: UIViewController
fileprivate func setupNavBar()
{
- // 自定义导航栏必须设置这个属性!!!!!!
- customNavBar = navBar
view.addSubview(navBar)
- navBar.items = [navItem]
- // 导航条背景颜色
- navBar.barTintColor = MainNavBarColor
- // 导航条标题颜色
- navBar.titleTextAttributes = [NSForegroundColorAttributeName:UIColor.white]
- // 导航条左右按钮字体颜色
- navBar.tintColor = UIColor.white
+
+ // 设置自定义导航栏背景图片
+ navBar.barBackgroundImage = UIImage(named: "millcolorGrad")
+
+ // 设置自定义导航栏背景颜色
+ // navBar.backgroundColor = MainNavBarColor
+
+ // 设置自定义导航栏标题颜色
+ navBar.titleLabelColor = .white
+
+ // 设置自定义导航栏左右按钮字体颜色
+ navBar.wr_setTintColor(color: .white)
+
+ if self.navigationController?.childViewControllers.count != 1 {
+ navBar.wr_setLeftButton(title: "<<", titleColor: UIColor.white)
+ }
+ }
+
+ @objc fileprivate func back()
+ {
+ _ = navigationController?.popViewController(animated: true)
}
}
diff --git a/WRNavigationBar_swift/WRNavigationBar_swift/Demos/CustomListController.swift b/WRNavigationBar_swift/WRNavigationBar_swift/Demos/CustomListController.swift
index 9be2fa5..5b08864 100644
--- a/WRNavigationBar_swift/WRNavigationBar_swift/Demos/CustomListController.swift
+++ b/WRNavigationBar_swift/WRNavigationBar_swift/Demos/CustomListController.swift
@@ -22,12 +22,11 @@ class CustomListController: BaseViewController
tableView.dataSource = self
tableView.delegate = self
tableView.backgroundColor = UIColor.white
+ if #available(iOS 11.0, *) {
+ tableView.contentInsetAdjustmentBehavior = .never
+ }
view.insertSubview(navBar, aboveSubview: tableView)
- navItem.title = "自定义导航栏"
-
- navBarBarTintColor = UIColor.init(red: 247/255.0, green: 247/255.0, blue: 247/255.0, alpha: 1.0)
- navBarTitleColor = .black
- statusBarStyle = .default
+ navBar.title = "自定义导航栏"
}
}
@@ -45,7 +44,11 @@ extension CustomListController: UITableViewDelegate, UITableViewDataSource
var str:String? = nil
switch indexPath.row {
case 0:
- str = "主页";
+ str = "主页"
+ case 1:
+ str = "导航栏显示图片"
+ case 2:
+ str = "实现导航栏渐变色的另一种方式"
default:
str = ""
}
@@ -64,6 +67,10 @@ extension CustomListController: UITableViewDelegate, UITableViewDataSource
switch indexPath.row {
case 0:
navigationController?.pushViewController(CustomNavBarController(), animated: true)
+ case 1:
+ navigationController?.pushViewController(ImageNavController(), animated: true)
+ case 2:
+ navigationController?.pushViewController(MillcolorGradController(), animated: true)
default:
break
}
diff --git a/WRNavigationBar_swift/WRNavigationBar_swift/Demos/CustomNavBarController.swift b/WRNavigationBar_swift/WRNavigationBar_swift/Demos/CustomNavBarController.swift
index dcb62f4..2cc35e5 100644
--- a/WRNavigationBar_swift/WRNavigationBar_swift/Demos/CustomNavBarController.swift
+++ b/WRNavigationBar_swift/WRNavigationBar_swift/Demos/CustomNavBarController.swift
@@ -17,7 +17,7 @@ class CustomNavBarController: BaseViewController
lazy var tableView:UITableView = {
let frame = CGRect(x: 0, y: 0, width: kScreenWidth, height: self.view.bounds.height)
let table:UITableView = UITableView(frame: frame, style: .plain)
- table.contentInset = UIEdgeInsetsMake(0, 0, CGFloat(kTabBarHeight), 0);
+ table.contentInset = UIEdgeInsetsMake(0, 0, 0, 0);
table.delegate = self
table.dataSource = self
return table
@@ -43,21 +43,21 @@ class CustomNavBarController: BaseViewController
topView.addSubview(imageView)
imageView.center = topView.center
tableView.tableHeaderView = topView
+ if #available(iOS 11.0, *) {
+ tableView.contentInsetAdjustmentBehavior = .never
+ }
view.insertSubview(navBar, aboveSubview: tableView)
- navItem.leftBarButtonItem = UIBarButtonItem(title: "<<", style: .plain, target: self, action: #selector(back))
- navItem.title = "个人中心"
+
+ navBar.title = "个人中心"
// 设置导航栏颜色
- navBarBarTintColor = UIColor.init(red: 247/255.0, green: 247/255.0, blue: 247/255.0, alpha: 1.0)
+ navBar.barBackgroundColor = UIColor(red: 247/255.0, green: 247/255.0, blue: 247/255.0, alpha: 1.0)
// 设置初始导航栏透明度
- navBarBackgroundAlpha = 0
-
- // 设置导航栏按钮
- navBarTintColor = .white
+ navBar.wr_setBackgroundAlpha(alpha: 0)
// 设置标题文字颜色
- navBarTitleColor = .white
+ navBar.titleLabelColor = UIColor.white
}
}
@@ -71,16 +71,16 @@ extension CustomNavBarController
if (offsetY > NAVBAR_COLORCHANGE_POINT)
{
let alpha = (offsetY - NAVBAR_COLORCHANGE_POINT) / CGFloat(kNavBarBottom)
- navBarBackgroundAlpha = alpha
- navBarTintColor = UIColor.black.withAlphaComponent(alpha)
- navBarTitleColor = UIColor.black.withAlphaComponent(alpha)
+ navBar.wr_setBackgroundAlpha(alpha: alpha)
+ navBar.wr_setTintColor(color: UIColor.black.withAlphaComponent(alpha))
+ navBar.titleLabelColor = UIColor.black.withAlphaComponent(alpha)
statusBarStyle = .default
}
else
{
- navBarBackgroundAlpha = 0
- navBarTintColor = .white
- navBarTitleColor = .white
+ navBar.wr_setBackgroundAlpha(alpha: 0)
+ navBar.wr_setTintColor(color: .white)
+ navBar.titleLabelColor = .white
statusBarStyle = .lightContent
}
}
@@ -108,13 +108,7 @@ extension CustomNavBarController:UITableViewDelegate,UITableViewDataSource
let vc:BaseViewController = BaseViewController()
vc.view.backgroundColor = UIColor.red
let str = String(format: "右滑返回查看效果 ", indexPath.row)
- vc.navItem.title = str
- vc.navItem.leftBarButtonItem = UIBarButtonItem(title: "返回", style: .plain, target: self, action: #selector(back))
+ vc.navBar.title = str
navigationController?.pushViewController(vc, animated: true)
}
-
- @objc fileprivate func back()
- {
- _ = navigationController?.popViewController(animated: true)
- }
}
diff --git a/WRNavigationBar_swift/WRNavigationBar_swift/Demos/ImageNavController.swift b/WRNavigationBar_swift/WRNavigationBar_swift/Demos/ImageNavController.swift
new file mode 100644
index 0000000..8843a5f
--- /dev/null
+++ b/WRNavigationBar_swift/WRNavigationBar_swift/Demos/ImageNavController.swift
@@ -0,0 +1,107 @@
+//
+// ImageNavController .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
+
+private let IMAGE_HEIGHT:CGFloat = 220
+private let NAVBAR_COLORCHANGE_POINT:CGFloat = IMAGE_HEIGHT - CGFloat(kNavBarBottom * 2)
+
+class ImageNavController: BaseViewController
+{
+ lazy var tableView:UITableView = {
+ let table:UITableView = UITableView(frame: CGRect.init(x: 0, y: 0, width: kScreenWidth, height: self.view.bounds.height), style: .plain)
+ table.contentInset = UIEdgeInsetsMake(0, 0, 0, 0);
+ table.delegate = self
+ table.dataSource = self
+ return table
+ }()
+ lazy var topView:UIImageView = {
+ let imgView = UIImageView(image: UIImage(named: "image7"))
+ imgView.frame = CGRect(x: 0, y: 0, width: kScreenWidth, height: IMAGE_HEIGHT)
+ imgView.contentMode = UIViewContentMode.scaleAspectFill
+ imgView.clipsToBounds = true
+ return imgView
+ }()
+
+ override func viewDidLoad()
+ {
+ super.viewDidLoad()
+ navBar.title = "玛丽莲·梦露"
+ view.backgroundColor = UIColor.red
+ view.addSubview(tableView)
+ tableView.tableHeaderView = topView
+ if #available(iOS 11.0, *) {
+ tableView.contentInsetAdjustmentBehavior = .never
+ }
+ view.insertSubview(navBar, aboveSubview: tableView)
+
+ // 设置导航栏显示图片
+ navBar.barBackgroundImage = UIImage(named: "imageNav")
+
+ // 设置初始导航栏透明度
+ navBar.wr_setBackgroundAlpha(alpha: 0)
+
+ // 设置导航栏按钮和标题颜色
+ navBar.wr_setTintColor(color: .white)
+
+ // 设置状态栏style
+ statusBarStyle = .lightContent
+ }
+
+ deinit {
+ tableView.delegate = nil
+ print("FirstVC deinit")
+ }
+}
+
+
+// MARK: - 滑动改变导航栏透明度、标题颜色、左右按钮颜色、状态栏颜色
+extension ImageNavController
+{
+ func scrollViewDidScroll(_ scrollView: UIScrollView)
+ {
+ let offsetY = scrollView.contentOffset.y
+ if (offsetY > NAVBAR_COLORCHANGE_POINT)
+ {
+ let alpha = (offsetY - NAVBAR_COLORCHANGE_POINT) / CGFloat(kNavBarBottom)
+ navBar.wr_setBackgroundAlpha(alpha: alpha)
+ }
+ else
+ {
+ navBar.wr_setBackgroundAlpha(alpha: 0)
+ }
+ }
+}
+
+
+extension ImageNavController:UITableViewDelegate,UITableViewDataSource
+{
+ func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
+ return 40
+ }
+
+ func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
+ {
+ let cell = UITableViewCell.init(style: .default, reuseIdentifier: nil)
+ let str = String(format: "WRNavigationBar %zd", indexPath.row)
+ cell.textLabel?.text = str
+ cell.textLabel?.font = UIFont.systemFont(ofSize: 15)
+ return cell
+ }
+
+ func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)
+ {
+ tableView.deselectRow(at: indexPath, animated: true)
+ let vc:BaseViewController = BaseViewController()
+ vc.view.backgroundColor = UIColor.red
+ let str = String(format: "右滑返回查看效果 ", indexPath.row)
+ vc.navBar.title = str
+ navigationController?.pushViewController(vc, animated: true)
+ }
+}
diff --git a/WRNavigationBar_swift/WRNavigationBar_swift/Demos/MillcolorGradController.swift b/WRNavigationBar_swift/WRNavigationBar_swift/Demos/MillcolorGradController.swift
new file mode 100644
index 0000000..e956dab
--- /dev/null
+++ b/WRNavigationBar_swift/WRNavigationBar_swift/Demos/MillcolorGradController.swift
@@ -0,0 +1,104 @@
+//
+// ImageNavController .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
+
+private let IMAGE_HEIGHT:CGFloat = 250
+private let NAVBAR_COLORCHANGE_POINT:CGFloat = IMAGE_HEIGHT - CGFloat(kNavBarBottom * 2)
+
+class MillcolorGradController: BaseViewController
+{
+ lazy var tableView:UITableView = {
+ let table:UITableView = UITableView(frame: CGRect.init(x: 0, y: 0, width: kScreenWidth, height: self.view.bounds.height), style: .plain)
+ table.contentInset = UIEdgeInsetsMake(0, 0, 0, 0);
+ table.delegate = self
+ table.dataSource = self
+ return table
+ }()
+ lazy var topView:UIImageView = {
+ let imgView = UIImageView(image: UIImage(named: "image8"))
+ imgView.frame = CGRect(x: 0, y: 0, width: kScreenWidth, height: IMAGE_HEIGHT)
+ imgView.contentMode = UIViewContentMode.scaleAspectFill
+ imgView.clipsToBounds = true
+ return imgView
+ }()
+
+ override func viewDidLoad()
+ {
+ super.viewDidLoad()
+ navBar.title = "奥黛丽·赫本"
+ view.backgroundColor = UIColor.red
+ view.addSubview(tableView)
+ tableView.tableHeaderView = topView
+ if #available(iOS 11.0, *) {
+ tableView.contentInsetAdjustmentBehavior = .never
+ }
+ view.insertSubview(navBar, aboveSubview: tableView)
+
+ // 设置初始导航栏透明度
+ navBar.wr_setBackgroundAlpha(alpha: 0)
+
+ // 设置导航栏按钮和标题颜色
+ navBar.wr_setTintColor(color: .white)
+
+ // 设置状态栏style
+ statusBarStyle = .lightContent
+ }
+
+ deinit {
+ tableView.delegate = nil
+ print("FirstVC deinit")
+ }
+}
+
+
+// MARK: - 滑动改变导航栏透明度、标题颜色、左右按钮颜色、状态栏颜色
+extension MillcolorGradController
+{
+ func scrollViewDidScroll(_ scrollView: UIScrollView)
+ {
+ let offsetY = scrollView.contentOffset.y
+ if (offsetY > NAVBAR_COLORCHANGE_POINT)
+ {
+ let alpha = (offsetY - NAVBAR_COLORCHANGE_POINT) / CGFloat(kNavBarBottom)
+ navBar.wr_setBackgroundAlpha(alpha: alpha)
+ }
+ else
+ {
+ navBar.wr_setBackgroundAlpha(alpha: 0)
+ }
+ }
+}
+
+
+extension MillcolorGradController:UITableViewDelegate,UITableViewDataSource
+{
+ func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
+ return 40
+ }
+
+ func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
+ {
+ let cell = UITableViewCell.init(style: .default, reuseIdentifier: nil)
+ let str = String(format: "WRNavigationBar %zd", indexPath.row)
+ cell.textLabel?.text = str
+ cell.textLabel?.font = UIFont.systemFont(ofSize: 15)
+ return cell
+ }
+
+ func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)
+ {
+ tableView.deselectRow(at: indexPath, animated: true)
+ let vc:BaseViewController = BaseViewController()
+ vc.view.backgroundColor = UIColor.red
+ let str = String(format: "右滑返回查看效果 ", indexPath.row)
+ vc.navBar.title = str
+ navigationController?.pushViewController(vc, animated: true)
+ }
+}
diff --git a/WRNavigationBar_swift/WRNavigationBar_swift/Demos/MoveListController.swift b/WRNavigationBar_swift/WRNavigationBar_swift/Demos/MoveListController.swift
index dcf4c5a..3bbe554 100644
--- a/WRNavigationBar_swift/WRNavigationBar_swift/Demos/MoveListController.swift
+++ b/WRNavigationBar_swift/WRNavigationBar_swift/Demos/MoveListController.swift
@@ -48,8 +48,6 @@ extension MoveListController: UITableViewDelegate, UITableViewDataSource
case 0:
str = "超过临界点移动导航栏";
case 1:
- str = "超过临界点多少,移动导航栏多少(不会超过44)";
- case 2:
str = "没有系统返回按钮的情况";
default:
str = ""
@@ -70,8 +68,6 @@ extension MoveListController: UITableViewDelegate, UITableViewDataSource
case 0:
navigationController?.pushViewController(SecondViewController(), animated: true)
case 1:
- navigationController?.pushViewController(ThirdViewController(), animated: true)
- case 2:
navigationController?.pushViewController(SixthViewController(), animated: true)
default:
break
diff --git a/WRNavigationBar_swift/WRNavigationBar_swift/Demos/NormalListController.swift b/WRNavigationBar_swift/WRNavigationBar_swift/Demos/NormalListController.swift
index 9300018..837f2f9 100644
--- a/WRNavigationBar_swift/WRNavigationBar_swift/Demos/NormalListController.swift
+++ b/WRNavigationBar_swift/WRNavigationBar_swift/Demos/NormalListController.swift
@@ -9,7 +9,7 @@
import UIKit
-let kNavBarBottom = 64
+let kNavBarBottom = WRNavigationBar.navBarBottom()
class NormalListController: UIViewController
{
@@ -23,6 +23,9 @@ class NormalListController: UIViewController
tableView.dataSource = self
tableView.delegate = self
tableView.backgroundColor = UIColor.white
+
+ // 改变标题文字大小
+ // navigationController?.navigationBar.titleTextAttributes = [NSFontAttributeName:UIFont.systemFont(ofSize: 22)]
}
}
@@ -53,6 +56,8 @@ extension NormalListController: UITableViewDelegate, UITableViewDataSource
str = "QQ我的资料页"
case 5:
str = "蚂蚁森林"
+ case 6:
+ str = "连续多个界面导航栏透明"
default:
str = ""
}
@@ -81,6 +86,8 @@ extension NormalListController: UITableViewDelegate, UITableViewDataSource
navigationController?.pushViewController(QQMineController(), animated: true)
case 5:
navigationController?.pushViewController(AntForestController(), animated: true)
+ case 6:
+ navigationController?.pushViewController(AllTransparent(), animated: true)
default:
break
}
diff --git a/WRNavigationBar_swift/WRNavigationBar_swift/Demos/QQAppController.swift b/WRNavigationBar_swift/WRNavigationBar_swift/Demos/QQAppController.swift
index c7f5655..ac53622 100644
--- a/WRNavigationBar_swift/WRNavigationBar_swift/Demos/QQAppController.swift
+++ b/WRNavigationBar_swift/WRNavigationBar_swift/Demos/QQAppController.swift
@@ -106,7 +106,7 @@ extension QQAppController
extension QQAppController: UITableViewDelegate,UITableViewDataSource
{
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
- return 15
+ return 25
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
diff --git a/WRNavigationBar_swift/WRNavigationBar_swift/Demos/QQMineController.swift b/WRNavigationBar_swift/WRNavigationBar_swift/Demos/QQMineController.swift
index 7ae6224..84c0e8d 100644
--- a/WRNavigationBar_swift/WRNavigationBar_swift/Demos/QQMineController.swift
+++ b/WRNavigationBar_swift/WRNavigationBar_swift/Demos/QQMineController.swift
@@ -17,7 +17,7 @@ class QQMineController: UIViewController
lazy var tableView:UITableView = {
let table:UITableView = UITableView(frame: CGRect.init(x: 0, y: 0, width: kScreenWidth, height: self.view.bounds.height), style: .plain)
table.backgroundColor = UIColor.clear
- table.contentInset = UIEdgeInsetsMake(-64, 0, 0, 0);
+ table.contentInset = UIEdgeInsetsMake(-CGFloat(kNavBarBottom), 0, 0, 0);
table.delegate = self
table.dataSource = self
return table
@@ -46,7 +46,7 @@ class QQMineController: UIViewController
return imgView
}()
lazy var topView:UIView = {
- let view = UIView(frame: CGRect(x: 0, y: 64, width: kScreenWidth, height: IMAGE_HEIGHT))
+ let view = UIView(frame: CGRect(x: 0, y: CGFloat(kNavBarBottom), width: kScreenWidth, height: IMAGE_HEIGHT))
view.backgroundColor = UIColor.clear
return view
}()
@@ -122,7 +122,7 @@ extension QQMineController
extension QQMineController:UITableViewDelegate,UITableViewDataSource
{
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
- return 20
+ return 25
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
diff --git a/WRNavigationBar_swift/WRNavigationBar_swift/Demos/SecondViewController.swift b/WRNavigationBar_swift/WRNavigationBar_swift/Demos/SecondViewController.swift
index 41da9af..366008d 100644
--- a/WRNavigationBar_swift/WRNavigationBar_swift/Demos/SecondViewController.swift
+++ b/WRNavigationBar_swift/WRNavigationBar_swift/Demos/SecondViewController.swift
@@ -15,7 +15,7 @@ class SecondViewController: UIViewController
{
lazy var tableView:UITableView = {
let table:UITableView = UITableView(frame: CGRect.init(x: 0, y: 0, width: kScreenWidth, height: self.view.bounds.height), style: .plain)
- table.contentInset = UIEdgeInsetsMake(-64, 0, 0, 0);
+ table.contentInset = UIEdgeInsetsMake(-CGFloat(kNavBarBottom), 0, 0, 0);
table.delegate = self
table.dataSource = self
return table
diff --git a/WRNavigationBar_swift/WRNavigationBar_swift/Demos/SixthViewController.swift b/WRNavigationBar_swift/WRNavigationBar_swift/Demos/SixthViewController.swift
index 7b6bb6f..afb67a7 100644
--- a/WRNavigationBar_swift/WRNavigationBar_swift/Demos/SixthViewController.swift
+++ b/WRNavigationBar_swift/WRNavigationBar_swift/Demos/SixthViewController.swift
@@ -15,7 +15,7 @@ class SixthViewController: UIViewController
{
lazy var tableView:UITableView = {
let table:UITableView = UITableView(frame: CGRect.init(x: 0, y: 0, width: kScreenWidth, height: self.view.bounds.height), style: .plain)
- table.contentInset = UIEdgeInsetsMake(-64, 0, 0, 0);
+ table.contentInset = UIEdgeInsetsMake(-CGFloat(kNavBarBottom), 0, 0, 0);
table.delegate = self
table.dataSource = self
return table
@@ -35,7 +35,7 @@ class SixthViewController: UIViewController
self.navigationItem.leftBarButtonItem = UIBarButtonItem(title: "自定义返回", style: .done, target: self, action: #selector(back))
}
- func back() {
+ @objc func back() {
_ = self.navigationController?.popViewController(animated: true)
}
diff --git a/WRNavigationBar_swift/WRNavigationBar_swift/Demos/ThirdViewController.swift b/WRNavigationBar_swift/WRNavigationBar_swift/Demos/ThirdViewController.swift
deleted file mode 100644
index f1cc156..0000000
--- a/WRNavigationBar_swift/WRNavigationBar_swift/Demos/ThirdViewController.swift
+++ /dev/null
@@ -1,164 +0,0 @@
-//
-// ThirdViewController.swift
-// WRNavigationBar_swift
-//
-// Created by wangrui on 2017/4/21.
-// Copyright © 2017年 wangrui. All rights reserved.
-//
-// Github地址:https://github.com/wangrui460/WRNavigationBar_swift
-
-import UIKit
-
-
-class ThirdViewController: UIViewController
-{
- fileprivate var NAVBAR_TRANSLATION_POINT:CGFloat = 0
- fileprivate var lastOffsetY:CGFloat = 0
-
- lazy var tableView:UITableView = {
- let table:UITableView = UITableView(frame: CGRect.init(x: 0, y: 0, width: kScreenWidth, height: self.view.bounds.height), style: .plain)
- table.contentInset = UIEdgeInsetsMake(-64, 0, 0, 0);
- table.delegate = self
- table.dataSource = self
- return table
- }()
- lazy var imageView:UIImageView = {
- let imgView = UIImageView(image: UIImage(named: "image2"))
- return imgView
- }()
-
- override func viewDidLoad()
- {
- super.viewDidLoad()
- title = "WR"
- view.backgroundColor = UIColor.red
- view.addSubview(tableView)
- tableView.tableHeaderView = imageView
- }
-
- deinit {
- tableView.delegate = nil
- print("ThirdVC deinit")
- }
-}
-
-
-// MARK: - viewWillAppear .. ScrollViewDidScroll
-extension ThirdViewController
-{
- override func viewDidAppear(_ animated: Bool)
- {
- super.viewDidAppear(animated)
- tableView.delegate = self;
- }
-
- override func viewWillDisappear(_ animated: Bool)
- {
- super.viewWillDisappear(animated)
- tableView.delegate = nil
- navigationController?.navigationBar.wr_setTranslationY(translationY: 0)
- }
-
- func scrollViewDidEndDecelerating(_ scrollView: UIScrollView)
- {
- stopScroll(scrollView)
- }
-
- func scrollViewDidEndDragging(_ scrollView: UIScrollView, willDecelerate decelerate: Bool)
- {
- if decelerate == false {
- stopScroll(scrollView)
- }
- }
-
- func stopScroll(_ scrollView: UIScrollView)
- {
- let offsetY = scrollView.contentOffset.y
- // 向上滑动的距离
- let scrollUpHeight = offsetY - NAVBAR_TRANSLATION_POINT
- if (scrollUpHeight >= 22)
- { // 超过导航栏高度的一半,只显示状态栏
- UIView.animate(withDuration: 0.3, animations: { [weak self] in
- if let weakSelf = self {
- weakSelf.setNavigationBarTransform(scrollUpHeight: 44)
- }
- })
- print("point:\(NAVBAR_TRANSLATION_POINT)")
- }
- else
- { // 没有超过导航栏高度的一半,导航栏全部显示
- UIView.animate(withDuration: 0.3, animations: { [weak self] in
- if let weakSelf = self {
- weakSelf.setNavigationBarTransform(scrollUpHeight: 0)
- }
- })
- print("point:\(NAVBAR_TRANSLATION_POINT)")
- }
- NAVBAR_TRANSLATION_POINT = offsetY
- }
-
- func scrollViewDidScroll(_ scrollView: UIScrollView)
- {
- let offsetY = scrollView.contentOffset.y
- // 向上滑动的距离
- let isScrollup = (offsetY - lastOffsetY) > 0 ? true : false
- let scrollUpHeight = (offsetY - NAVBAR_TRANSLATION_POINT) > 44 ? 44 : (offsetY - NAVBAR_TRANSLATION_POINT)
- let curTransformY = navigationController?.navigationBar.wr_getTranslationY()
-
-
- if isScrollup == true
- { // 上滑
- if curTransformY == -44 {
- return
- }
- else
- {
- if offsetY > 0 {
- setNavigationBarTransform(scrollUpHeight: scrollUpHeight)
- }
- }
- }
- else
- { // 下滑
- UIView.animate(withDuration: 0.3, animations: { [weak self] in
- if let weakSelf = self {
- weakSelf.setNavigationBarTransform(scrollUpHeight: 0)
- }
- })
- }
-
- lastOffsetY = offsetY
- }
-
- func setNavigationBarTransform(scrollUpHeight:CGFloat)
- {
- navigationController?.navigationBar.wr_setTranslationY(translationY: -scrollUpHeight)
- // 有系统的返回按钮,所以 hasSystemBackIndicator = YES
- let curTransformY = navigationController?.navigationBar.wr_getTranslationY() ?? 0
- navigationController?.navigationBar.wr_setBarButtonItemsAlpha(alpha: 1 - (-curTransformY / 44.0), hasSystemBackIndicator: true)
- }
-}
-
-
-extension ThirdViewController:UITableViewDelegate,UITableViewDataSource
-{
- func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
- return 15
- }
-
- func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
- {
- let cell = UITableViewCell.init(style: .default, reuseIdentifier: nil)
- let str = String(format: "WRNavigationBar %zd", indexPath.row)
- cell.textLabel?.text = str
- cell.textLabel?.font = UIFont.systemFont(ofSize: 15)
- return cell
- }
-
- func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)
- {
- tableView.deselectRow(at: indexPath, animated: true)
-
- // 做成这种样式,最好不要有点击事件
- }
-}
diff --git a/WRNavigationBar_swift/WRNavigationBar_swift/Demos/WeiBoMineController.swift b/WRNavigationBar_swift/WRNavigationBar_swift/Demos/WeiBoMineController.swift
index 46fcfa9..d121f1a 100644
--- a/WRNavigationBar_swift/WRNavigationBar_swift/Demos/WeiBoMineController.swift
+++ b/WRNavigationBar_swift/WRNavigationBar_swift/Demos/WeiBoMineController.swift
@@ -16,7 +16,7 @@ class WeiBoMineController: UIViewController
{
lazy var tableView:UITableView = {
let table:UITableView = UITableView(frame: CGRect.init(x: 0, y: 0, width: kScreenWidth, height: self.view.bounds.height), style: .plain)
- table.contentInset = UIEdgeInsetsMake(-64, 0, 0, 0);
+ table.contentInset = UIEdgeInsetsMake(-CGFloat(kNavBarBottom), 0, 0, 0);
table.delegate = self
table.dataSource = self
return table
@@ -43,7 +43,7 @@ class WeiBoMineController: UIViewController
let label = UILabel()
label.backgroundColor = UIColor.clear
label.textColor = UIColor.white
- label.text = "关注 121 | 粉丝 17"
+ label.text = "关注 121 | 粉丝 891"
label.textAlignment = .center
label.font = .boldSystemFont(ofSize: 14)
return label
@@ -90,6 +90,9 @@ class WeiBoMineController: UIViewController
// 设置导航栏按钮和标题颜色
navBarTintColor = .white
+
+ // 如果需要隐藏导航栏底部分割线,设置 hideShadowImage 为true
+ // hideShadowImage = true
}
deinit {
diff --git a/WRNavigationBar_swift/WRNavigationBar_swift/Demos/ZhiHuController.swift b/WRNavigationBar_swift/WRNavigationBar_swift/Demos/ZhiHuController.swift
index 2457263..ffb14af 100644
--- a/WRNavigationBar_swift/WRNavigationBar_swift/Demos/ZhiHuController.swift
+++ b/WRNavigationBar_swift/WRNavigationBar_swift/Demos/ZhiHuController.swift
@@ -102,7 +102,7 @@ extension ZhiHuController
extension ZhiHuController: UITableViewDelegate,UITableViewDataSource
{
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
- return 15
+ return 25
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
diff --git a/WRNavigationBar_swift/WRNavigationBar_swift/WRNavigationBar/WRCustomNavigationBar.swift b/WRNavigationBar_swift/WRNavigationBar_swift/WRNavigationBar/WRCustomNavigationBar.swift
new file mode 100644
index 0000000..5066e10
--- /dev/null
+++ b/WRNavigationBar_swift/WRNavigationBar_swift/WRNavigationBar/WRCustomNavigationBar.swift
@@ -0,0 +1,301 @@
+//
+// WRCustomNavigationBar.swift
+// WRNavigationBar_swift
+//
+// Created by itwangrui on 2017/11/25.
+// Copyright © 2017年 wangrui. All rights reserved.
+//
+
+import UIKit
+
+fileprivate let WRDefaultTitleSize:CGFloat = 18
+fileprivate let WRDefaultTitleColor = UIColor.black
+fileprivate let WRDefaultBackgroundColor = UIColor.white
+fileprivate let WRScreenWidth = UIScreen.main.bounds.size.width
+
+
+// MARK: - Router
+extension UIViewController
+{
+ // A页面 弹出 登录页面B
+ // presentedViewController: A页面
+ // presentingViewController: B页面
+
+ func wr_toLastViewController(animated:Bool)
+ {
+ if self.navigationController != nil
+ {
+ if self.navigationController?.viewControllers.count == 1
+ {
+ self.dismiss(animated: animated, completion: nil)
+ } else {
+ self.navigationController?.popViewController(animated: animated)
+ }
+ }
+ else if self.presentingViewController != nil {
+ self.dismiss(animated: animated, completion: nil)
+ }
+ }
+
+ class func wr_currentViewController() -> UIViewController
+ {
+ if let rootVC = UIApplication.shared.delegate?.window??.rootViewController {
+ return self.wr_currentViewController(from: rootVC)
+ } else {
+ return UIViewController()
+ }
+ }
+
+ class func wr_currentViewController(from fromVC:UIViewController) -> UIViewController
+ {
+ if fromVC.isKind(of: UINavigationController.self) {
+ let navigationController = fromVC as! UINavigationController
+ return wr_currentViewController(from: navigationController.viewControllers.last!)
+ }
+ else if fromVC.isKind(of: UITabBarController.self) {
+ let tabBarController = fromVC as! UITabBarController
+ return wr_currentViewController(from: tabBarController.selectedViewController!)
+ }
+ else if fromVC.presentedViewController != nil {
+ return wr_currentViewController(from:fromVC.presentingViewController!)
+ }
+ else {
+ return fromVC
+ }
+ }
+}
+
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////
+class WRCustomNavigationBar: UIView
+{
+ var onClickLeftButton:(()->())?
+ var onClickRightButton:(()->())?
+ var title:String? {
+ willSet {
+ titleLabel.isHidden = false
+ titleLabel.text = newValue
+ }
+ }
+ var titleLabelColor:UIColor? {
+ willSet {
+ titleLabel.textColor = newValue
+ }
+ }
+ var titleLabelFont:UIFont? {
+ willSet {
+ titleLabel.font = newValue
+ }
+ }
+ var barBackgroundColor:UIColor? {
+ willSet {
+ backgroundImageView.isHidden = true
+ backgroundView.isHidden = false
+ backgroundView.backgroundColor = newValue
+ }
+ }
+ var barBackgroundImage:UIImage? {
+ willSet {
+ backgroundView.isHidden = true
+ backgroundImageView.isHidden = false
+ backgroundImageView.image = newValue
+ }
+ }
+
+ // fileprivate UI variable
+ fileprivate lazy var titleLabel:UILabel = {
+ let label = UILabel()
+ label.textColor = WRDefaultTitleColor
+ label.font = UIFont.systemFont(ofSize: WRDefaultTitleSize)
+ label.textAlignment = .center
+ label.isHidden = true
+ return label
+ }()
+
+ fileprivate lazy var leftButton:UIButton = {
+ let button = UIButton()
+ button.imageView?.contentMode = .center
+ button.isHidden = true
+ button.addTarget(self, action: #selector(clickBack), for: .touchUpInside)
+ return button
+ }()
+
+ fileprivate lazy var rightButton:UIButton = {
+ let button = UIButton()
+ button.imageView?.contentMode = .center
+ button.isHidden = true
+ button.addTarget(self, action: #selector(clickRight), for: .touchUpInside)
+ return button
+ }()
+
+ fileprivate lazy var bottomLine:UIView = {
+ let view = UIView()
+ view.backgroundColor = UIColor(red: (218.0/255.0), green: (218.0/255.0), blue: (218.0/255.0), alpha: 1.0)
+ return view
+ }()
+
+ fileprivate lazy var backgroundView:UIView = {
+ let view = UIView()
+ return view
+ }()
+
+ fileprivate lazy var backgroundImageView:UIImageView = {
+ let imgView = UIImageView()
+ imgView.isHidden = true
+ return imgView
+ }()
+
+ // fileprivate other variable
+ fileprivate static var isIphoneX:Bool {
+ get {
+ return UIScreen.main.bounds.equalTo(CGRect(x: 0, y: 0, width: 375, height: 812))
+ }
+ }
+ fileprivate static var navBarBottom:Int {
+ get {
+ return isIphoneX ? 88 : 64
+ }
+ }
+
+ // init
+ class func CustomNavigationBar() -> WRCustomNavigationBar {
+ let frame = CGRect(x: 0, y: 0, width: WRScreenWidth, height: CGFloat(navBarBottom))
+ return WRCustomNavigationBar(frame: frame)
+ }
+ override init(frame: CGRect) {
+ super.init(frame: frame)
+ setupView()
+ }
+ required init?(coder aDecoder: NSCoder) {
+ super.init(coder: aDecoder)
+ setupView()
+ }
+
+ func setupView()
+ {
+ addSubview(backgroundView)
+ addSubview(backgroundImageView)
+ addSubview(leftButton)
+ addSubview(titleLabel)
+ addSubview(rightButton)
+ addSubview(bottomLine)
+ updateFrame()
+ backgroundColor = UIColor.clear
+ backgroundView.backgroundColor = WRDefaultBackgroundColor
+ }
+ func updateFrame()
+ {
+ let top:CGFloat = WRCustomNavigationBar.isIphoneX ? 44 : 20
+ let margin:CGFloat = 0
+ let buttonHeight:CGFloat = 44
+ let buttonWidth:CGFloat = 44
+ let titleLabelHeight:CGFloat = 44
+ let titleLabelWidth:CGFloat = 180
+
+ backgroundView.frame = self.bounds
+ backgroundImageView.frame = self.bounds
+ leftButton.frame = CGRect(x: margin, y: top, width: buttonWidth, height: buttonHeight)
+ rightButton.frame = CGRect(x: WRScreenWidth-buttonWidth-margin, y: top, width: buttonWidth, height: buttonHeight)
+ titleLabel.frame = CGRect(x: (WRScreenWidth-titleLabelWidth)/2.0, y: top, width: titleLabelWidth, height: titleLabelHeight)
+ bottomLine.frame = CGRect(x: 0, y: bounds.height-0.5, width: WRScreenWidth, height: 0.5)
+ }
+}
+
+
+extension WRCustomNavigationBar
+{
+ func wr_setBottomLineHidden(hidden:Bool) {
+ bottomLine.isHidden = hidden
+ }
+ func wr_setBackgroundAlpha(alpha:CGFloat) {
+ backgroundView.alpha = alpha
+ backgroundImageView.alpha = alpha
+ bottomLine.alpha = alpha
+ }
+ func wr_setTintColor(color:UIColor) {
+ leftButton.setTitleColor(color, for: .normal)
+ rightButton.setTitleColor(color, for: .normal)
+ titleLabel.textColor = color
+ }
+
+ // 左右按钮共有方法
+ func wr_setLeftButton(normal:UIImage, highlighted:UIImage) {
+ wr_setLeftButton(normal: normal, highlighted: highlighted, title: nil, titleColor: nil)
+ }
+ func wr_setLeftButton(image:UIImage) {
+ wr_setLeftButton(normal: image, highlighted: image, title: nil, titleColor: nil)
+ }
+ func wr_setLeftButton(title:String, titleColor:UIColor) {
+ wr_setLeftButton(normal: nil, highlighted: nil, title: title, titleColor: titleColor)
+ }
+
+ func wr_setRightButton(normal:UIImage, highlighted:UIImage) {
+ wr_setRightButton(normal: normal, highlighted: highlighted, title: nil, titleColor: nil)
+ }
+ func wr_setRightButton(image:UIImage) {
+ wr_setRightButton(normal: image, highlighted: image, title: nil, titleColor: nil)
+ }
+ func wr_setRightButton(title:String, titleColor:UIColor) {
+ wr_setRightButton(normal: nil, highlighted: nil, title: title, titleColor: titleColor)
+ }
+
+
+ // 左右按钮私有方法
+ private func wr_setLeftButton(normal:UIImage?, highlighted:UIImage?, title:String?, titleColor:UIColor?) {
+ leftButton.isHidden = false
+ leftButton.setImage(normal, for: .normal)
+ leftButton.setImage(highlighted, for: .highlighted)
+ leftButton.setTitle(title, for: .normal)
+ leftButton.setTitleColor(titleColor, for: .normal)
+ }
+ private func wr_setRightButton(normal:UIImage?, highlighted:UIImage?, title:String?, titleColor:UIColor?) {
+ rightButton.isHidden = false
+ rightButton.setImage(normal, for: .normal)
+ rightButton.setImage(highlighted, for: .highlighted)
+ rightButton.setTitle(title, for: .normal)
+ rightButton.setTitleColor(titleColor, for: .normal)
+ }
+}
+
+
+// MARK: - 导航栏左右按钮事件
+extension WRCustomNavigationBar
+{
+ @objc func clickBack() {
+ if let onClickBack = onClickLeftButton {
+ onClickBack()
+ } else {
+ let currentVC = UIViewController.wr_currentViewController()
+ currentVC.wr_toLastViewController(animated: true)
+ }
+ }
+ @objc func clickRight() {
+ if let onClickRight = onClickRightButton {
+ onClickRight()
+ }
+ }
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/WRNavigationBar_swift/WRNavigationBar_swift/WRNavigationBar/WRCycleScrollView/WRCycleScrollView.swift b/WRNavigationBar_swift/WRNavigationBar_swift/WRNavigationBar/WRCycleScrollView/WRCycleScrollView.swift
index 3768856..47935a3 100644
--- a/WRNavigationBar_swift/WRNavigationBar_swift/WRNavigationBar/WRCycleScrollView/WRCycleScrollView.swift
+++ b/WRNavigationBar_swift/WRNavigationBar_swift/WRNavigationBar/WRCycleScrollView/WRCycleScrollView.swift
@@ -237,7 +237,7 @@ extension WRCycleScrollView
}
// 执行这个方法的前提是 isAutoScroll = true
- func changeCycleCell()
+ @objc func changeCycleCell()
{
if canChangeCycleCell == true
{
diff --git a/WRNavigationBar_swift/WRNavigationBar_swift/WRNavigationBar/WRNavigationBar.swift b/WRNavigationBar_swift/WRNavigationBar_swift/WRNavigationBar/WRNavigationBar.swift
index c1af906..1322e4c 100644
--- a/WRNavigationBar_swift/WRNavigationBar_swift/WRNavigationBar/WRNavigationBar.swift
+++ b/WRNavigationBar_swift/WRNavigationBar_swift/WRNavigationBar/WRNavigationBar.swift
@@ -9,10 +9,11 @@
import UIKit
-extension UINavigationBar
+extension UINavigationBar:WRAwakeProtocol
{
fileprivate struct AssociatedKeys {
- static var backgroundView:UIView = UIView()
+ static var backgroundView: UIView = UIView()
+ static var backgroundImageView: UIImageView = UIImageView()
}
fileprivate var backgroundView:UIView? {
@@ -27,14 +28,46 @@ extension UINavigationBar
}
}
+ 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: 64))
+ 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)
}
@@ -44,8 +77,17 @@ extension UINavigationBar
// set _UIBarBackground alpha (_UIBarBackground subviews alpha <= _UIBarBackground alpha)
fileprivate func wr_setBackgroundAlpha(alpha:CGFloat)
{
- let barBackgroundView = subviews[0]
- barBackgroundView.alpha = alpha
+ 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的透明度
@@ -104,15 +146,73 @@ extension UINavigationBar
{
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
+extension UINavigationController: WRFatherAwakeProtocol
{
override open var preferredStatusBarStyle: UIStatusBarStyle {
- return topViewController?.statusBarStyle ?? UIColor.defaultStatusBarStyle
+ return topViewController?.statusBarStyle ?? WRNavigationBar.defaultStatusBarStyle
+ }
+
+ fileprivate func setNeedsNavigationBarUpdate(backgroundImage: UIImage)
+ {
+ navigationBar.wr_setBackgroundImage(image: backgroundImage)
}
fileprivate func setNeedsNavigationBarUpdate(barTintColor: UIColor)
@@ -128,43 +228,55 @@ extension UINavigationController
fileprivate func setNeedsNavigationBarUpdate(tintColor: UIColor) {
navigationBar.tintColor = tintColor
}
+
+ fileprivate func setNeedsNavigationBarUpdate(hideShadowImage: Bool)
+ {
+ navigationBar.shadowImage = (hideShadowImage == true) ? UIImage() : nil
+ }
- fileprivate func setNeedsNavigationBarUpdate(titleColor: UIColor) {
- navigationBar.titleTextAttributes = [NSForegroundColorAttributeName:titleColor]
+ 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 ?? .defaultNavBarBarTintColor
- let toBarTintColor = toVC?.navBarBarTintColor ?? .defaultNavBarBarTintColor
- let newBarTintColor = UIColor.middleColor(fromColor: fromBarTintColor, toColor: toBarTintColor, percent: progress)
+ 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)
// change navBarTintColor
- let fromTintColor = fromVC?.navBarTintColor ?? .defaultNavBarTintColor
- let toTintColor = toVC?.navBarTintColor ?? .defaultNavBarTintColor
- let newTintColor = UIColor.middleColor(fromColor: fromTintColor, toColor: toTintColor, percent: progress)
+ 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)
// change navBarTitleColor
- let fromTitleColor = fromVC?.navBarTitleColor ?? .defaultNavBarTitleColor
- let toTitleColor = toVC?.navBarTitleColor ?? .defaultNavBarTitleColor
- let newTitleColor = UIColor.middleColor(fromColor: fromTitleColor, toColor: toTitleColor, percent: progress)
- setNeedsNavigationBarUpdate(titleColor: newTitleColor)
+// 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 ?? UIColor.defaultBackgroundAlpha
- let toBarBackgroundAlpha = toVC?.navBarBackgroundAlpha ?? UIColor.defaultBackgroundAlpha
- let newBarBackgroundAlpha = UIColor.middleAlpha(fromAlpha: fromBarBackgroundAlpha, toAlpha: toBarBackgroundAlpha, percent: progress)
+ 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
- open override class func initialize()
+ public static func fatherAwake()
{
- guard self == UINavigationController.self else { return }
DispatchQueue.once(token: onceToken)
{
let needSwizzleSelectorArr = [
@@ -173,13 +285,14 @@ extension UINavigationController
#selector(popToRootViewController),
#selector(pushViewController)
]
-
+
for selector in needSwizzleSelectorArr {
// _updateInteractiveTransition: => wr_updateInteractiveTransition:
let str = ("wr_" + selector.description).replacingOccurrences(of: "__", with: "_")
- let originalMethod = class_getInstanceMethod(self, selector)
- let swizzledMethod = class_getInstanceMethod(self, Selector(str))
- method_exchangeImplementations(originalMethod, swizzledMethod)
+ if let originalMethod = class_getInstanceMethod(self, selector),
+ let swizzledMethod = class_getInstanceMethod(self, Selector(str)) {
+ method_exchangeImplementations(originalMethod, swizzledMethod)
+ }
}
}
}
@@ -198,8 +311,9 @@ extension UINavigationController
}
// swizzling system method: popToViewController
- func wr_popToViewController(_ viewController: UIViewController, animated: Bool) -> [UIViewController]?
+ @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
@@ -217,7 +331,7 @@ extension UINavigationController
}
// swizzling system method: popToRootViewControllerAnimated
- func wr_popToRootViewControllerAnimated(_ animated: Bool) -> [UIViewController]?
+ @objc func wr_popToRootViewControllerAnimated(_ animated: Bool) -> [UIViewController]?
{
var displayLink:CADisplayLink? = CADisplayLink(target: self, selector: #selector(popNeedDisplay))
displayLink?.add(to: RunLoop.main, forMode: .commonModes)
@@ -234,7 +348,7 @@ extension UINavigationController
}
// change navigationBar barTintColor smooth before pop to current VC finished
- func popNeedDisplay()
+ @objc fileprivate func popNeedDisplay()
{
guard let topViewController = topViewController,
let coordinator = topViewController.transitionCoordinator else {
@@ -264,10 +378,10 @@ extension UINavigationController
}
// swizzling system method: pushViewController
- func wr_pushViewController(_ viewController: UIViewController, animated: Bool)
+ @objc func wr_pushViewController(_ viewController: UIViewController, animated: Bool)
{
var displayLink:CADisplayLink? = CADisplayLink(target: self, selector: #selector(pushNeedDisplay))
- displayLink?.add(to: RunLoop.main, forMode: .defaultRunLoopMode)
+ displayLink?.add(to: RunLoop.main, forMode: .commonModes)
CATransaction.setCompletionBlock {
displayLink?.invalidate()
displayLink = nil
@@ -281,7 +395,7 @@ extension UINavigationController
}
// change navigationBar barTintColor smooth before push to current VC finished or before pop to current VC finished
- func pushNeedDisplay()
+ @objc fileprivate func pushNeedDisplay()
{
guard let topViewController = topViewController,
let coordinator = topViewController.transitionCoordinator else {
@@ -330,8 +444,8 @@ extension UINavigationController: UINavigationBarDelegate
private func dealInteractionChanges(_ context: UIViewControllerTransitionCoordinatorContext)
{
let animations: (UITransitionContextViewControllerKey) -> () = {
- let curColor = context.viewController(forKey: $0)?.navBarBarTintColor ?? UIColor.defaultNavBarBarTintColor
- let curAlpha = context.viewController(forKey: $0)?.navBarBackgroundAlpha ?? UIColor.defaultBackgroundAlpha
+ 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)
@@ -356,7 +470,7 @@ extension UINavigationController: UINavigationBarDelegate
}
// swizzling system method: _updateInteractiveTransition
- func wr_updateInteractiveTransition(_ percentComplete: CGFloat)
+ @objc func wr_updateInteractiveTransition(_ percentComplete: CGFloat)
{
guard let topViewController = topViewController,
let coordinator = topViewController.transitionCoordinator else {
@@ -375,24 +489,27 @@ extension UINavigationController: UINavigationBarDelegate
//=============================================================================
// MARK: - store navigationBar barTintColor and tintColor every viewController
//=============================================================================
-extension UIViewController
+extension UIViewController: WRAwakeProtocol
{
fileprivate struct AssociatedKeys
{
static var pushToCurrentVCFinished: Bool = false
static var pushToNextVCFinished:Bool = false
- static var navBarBarTintColor: UIColor = UIColor.defaultNavBarBarTintColor
+ static var navBarBackgroundImage: UIImage = UIImage()
+
+ static var navBarBarTintColor: UIColor = WRNavigationBar.defaultNavBarBarTintColor
static var navBarBackgroundAlpha:CGFloat = 1.0
- static var navBarTintColor: UIColor = UIColor.defaultNavBarTintColor
- static var navBarTitleColor: UIColor = UIColor.defaultNavBarTitleColor
+ static var navBarTintColor: UIColor = WRNavigationBar.defaultNavBarTintColor
+ static var navBarTitleColor: UIColor = WRNavigationBar.defaultNavBarTitleColor
static var statusBarStyle: 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
- var pushToCurrentVCFinished:Bool {
+ fileprivate var pushToCurrentVCFinished:Bool {
get {
guard let isFinished = objc_getAssociatedObject(self, &AssociatedKeys.pushToCurrentVCFinished) as? Bool else {
return false
@@ -405,7 +522,7 @@ extension UIViewController
}
// navigationBar barTintColor can not change by currentVC when currentVC push to nextVC finished
- var pushToNextVCFinished:Bool {
+ fileprivate var pushToNextVCFinished:Bool {
get {
guard let isFinished = objc_getAssociatedObject(self, &AssociatedKeys.pushToNextVCFinished) as? Bool else {
return false
@@ -417,11 +534,31 @@ extension UIViewController
}
}
+ // 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 {
guard let barTintColor = objc_getAssociatedObject(self, &AssociatedKeys.navBarBarTintColor) as? UIColor else {
- return UIColor.defaultNavBarBarTintColor
+ return WRNavigationBar.defaultNavBarBarTintColor
}
return barTintColor
}
@@ -429,12 +566,11 @@ extension UIViewController
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)
+// let navBar = customNavBar as! UINavigationBar
+// navBar.wr_setBackgroundColor(color: newValue)
}
- else
- {
- if pushToCurrentVCFinished == true && pushToNextVCFinished == false {
+ else {
+ if canUpdateNavBarBarTintColorOrBackgroundAlpha == true {
navigationController?.setNeedsNavigationBarUpdate(barTintColor: newValue)
}
}
@@ -453,23 +589,32 @@ extension UIViewController
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)
+// let navBar = customNavBar as! UINavigationBar
+// navBar.wr_setBackgroundAlpha(alpha: newValue)
}
- else
- {
- if pushToCurrentVCFinished == true && pushToNextVCFinished == false {
+ 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 {
guard let tintColor = objc_getAssociatedObject(self, &AssociatedKeys.navBarTintColor) as? UIColor else {
- return UIColor.defaultNavBarTintColor
+ return WRNavigationBar.defaultNavBarTintColor
}
return tintColor
}
@@ -477,8 +622,8 @@ extension UIViewController
objc_setAssociatedObject(self, &AssociatedKeys.navBarTintColor, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
if customNavBar.isKind(of: UINavigationBar.self) {
- let navBar = customNavBar as! UINavigationBar
- navBar.tintColor = newValue
+// let navBar = customNavBar as! UINavigationBar
+// navBar.tintColor = newValue
}
else
{
@@ -493,7 +638,7 @@ extension UIViewController
var navBarTitleColor: UIColor {
get {
guard let titleColor = objc_getAssociatedObject(self, &AssociatedKeys.navBarTitleColor) as? UIColor else {
- return UIColor.defaultNavBarTitleColor
+ return WRNavigationBar.defaultNavBarTitleColor
}
return titleColor
}
@@ -501,8 +646,8 @@ extension UIViewController
objc_setAssociatedObject(self, &AssociatedKeys.navBarTitleColor, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
if customNavBar.isKind(of: UINavigationBar.self) {
- let navBar = customNavBar as! UINavigationBar
- navBar.titleTextAttributes = [NSForegroundColorAttributeName:newValue]
+// let navBar = customNavBar as! UINavigationBar
+// navBar.titleTextAttributes = [NSAttributedStringKey.foregroundColor:newValue]
}
else
{
@@ -517,7 +662,7 @@ extension UIViewController
var statusBarStyle: UIStatusBarStyle {
get {
guard let style = objc_getAssociatedObject(self, &AssociatedKeys.statusBarStyle) as? UIStatusBarStyle else {
- return UIColor.defaultStatusBarStyle
+ return WRNavigationBar.defaultStatusBarStyle
}
return style
}
@@ -527,6 +672,20 @@ extension UIViewController
}
}
+ // 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 {
@@ -542,12 +701,8 @@ extension UIViewController
// swizzling two system methods: viewWillAppear(_:) and viewWillDisappear(_:)
private static let onceToken = UUID().uuidString
- open override class func initialize()
+ @objc public static func wrAwake()
{
- guard self == UIViewController.self else {
- return
- }
-
DispatchQueue.once(token: onceToken)
{
let needSwizzleSelectors = [
@@ -555,39 +710,72 @@ extension UIViewController
#selector(viewWillDisappear(_:)),
#selector(viewDidAppear(_:))
]
-
+
for selector in needSwizzleSelectors
{
let newSelectorStr = "wr_" + selector.description
- let originalMethod = class_getInstanceMethod(self, selector)
- let swizzledMethod = class_getInstanceMethod(self, Selector(newSelectorStr))
- method_exchangeImplementations(originalMethod, swizzledMethod)
+ if let originalMethod = class_getInstanceMethod(self, selector),
+ let swizzledMethod = class_getInstanceMethod(self, Selector(newSelectorStr)) {
+ method_exchangeImplementations(originalMethod, swizzledMethod)
+ }
}
}
}
- func wr_viewWillAppear(_ animated: Bool)
+ @objc func wr_viewWillAppear(_ animated: Bool)
{
- pushToNextVCFinished = false
- navigationController?.setNeedsNavigationBarUpdate(tintColor: navBarTintColor)
- navigationController?.setNeedsNavigationBarUpdate(titleColor: navBarTitleColor)
+ if canUpdateNavigationBar() == true {
+ pushToNextVCFinished = false
+ navigationController?.setNeedsNavigationBarUpdate(tintColor: navBarTintColor)
+ navigationController?.setNeedsNavigationBarUpdate(titleColor: navBarTitleColor)
+ }
wr_viewWillAppear(animated)
}
- func wr_viewWillDisappear(_ animated: Bool)
+ @objc func wr_viewWillDisappear(_ animated: Bool)
{
- pushToNextVCFinished = true
+ if canUpdateNavigationBar() == true {
+ pushToNextVCFinished = true
+ }
wr_viewWillDisappear(animated)
}
- func wr_viewDidAppear(_ animated: Bool)
+ @objc func wr_viewDidAppear(_ animated: Bool)
{
- navigationController?.setNeedsNavigationBarUpdate(barTintColor: navBarBarTintColor)
- navigationController?.setNeedsNavigationBarUpdate(barBackgroundAlpha: navBarBackgroundAlpha)
- navigationController?.setNeedsNavigationBarUpdate(tintColor: navBarTintColor)
- navigationController?.setNeedsNavigationBarUpdate(titleColor: navBarTitleColor)
+
+ 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
+ {
+ 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
+ }
+ }
+
}
//====================================================================================
@@ -618,15 +806,18 @@ extension DispatchQueue {
//===========================================================================================
// MARK: - default navigationBar barTintColor、tintColor and statusBarStyle YOU CAN CHANGE!!!
//===========================================================================================
-extension UIColor
+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 {
@@ -639,6 +830,18 @@ extension UIColor
}
}
+ 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 {
@@ -675,6 +878,18 @@ extension UIColor
}
}
+ 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
@@ -714,8 +929,76 @@ extension UIColor
}
}
+extension WRNavigationBar
+{
+ class func isIphoneX() -> Bool {
+ return UIScreen.main.bounds.equalTo(CGRect(x: 0, y: 0, width: 375, height: 812))
+ }
+ 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.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)
+ 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 方法
+
diff --git "a/screenshots/\345\257\274\350\210\252\346\240\217\346\230\276\347\244\272\345\233\276\347\211\207.gif" "b/screenshots/\345\257\274\350\210\252\346\240\217\346\230\276\347\244\272\345\233\276\347\211\207.gif"
new file mode 100644
index 0000000..471df25
Binary files /dev/null and "b/screenshots/\345\257\274\350\210\252\346\240\217\346\230\276\347\244\272\345\233\276\347\211\207.gif" differ
diff --git "a/screenshots/\345\257\274\350\210\252\346\240\217\346\230\276\347\244\272\346\270\220\345\217\230\350\211\262.gif" "b/screenshots/\345\257\274\350\210\252\346\240\217\346\230\276\347\244\272\346\270\220\345\217\230\350\211\262.gif"
new file mode 100644
index 0000000..9452626
Binary files /dev/null and "b/screenshots/\345\257\274\350\210\252\346\240\217\346\230\276\347\244\272\346\270\220\345\217\230\350\211\262.gif" differ
diff --git "a/screenshots/\346\213\211\351\222\251App\351\246\226\351\241\265.gif" "b/screenshots/\346\213\211\351\222\251App\351\246\226\351\241\265.gif"
new file mode 100644
index 0000000..fa5249b
Binary files /dev/null and "b/screenshots/\346\213\211\351\222\251App\351\246\226\351\241\265.gif" differ
diff --git "a/screenshots/\350\277\236\347\273\255\345\244\232\344\270\252\347\225\214\351\235\242\345\257\274\350\210\252\346\240\217\351\200\217\346\230\216.gif" "b/screenshots/\350\277\236\347\273\255\345\244\232\344\270\252\347\225\214\351\235\242\345\257\274\350\210\252\346\240\217\351\200\217\346\230\216.gif"
new file mode 100644
index 0000000..480e5a6
Binary files /dev/null and "b/screenshots/\350\277\236\347\273\255\345\244\232\344\270\252\347\225\214\351\235\242\345\257\274\350\210\252\346\240\217\351\200\217\346\230\216.gif" differ