ProHUD/Source/HUDController.swift

176 lines
5.3 KiB
Swift
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//
// HUDController.swift
// ProHUD
//
// Created by xaoxuu on 2019/7/29.
// Copyright © 2019 Titan Studio. All rights reserved.
//
import UIKit
public class HUDController: UIViewController {
/// ID
public var identifier = String(Date().timeIntervalSince1970)
internal var willAppearCallback: (() -> Void)?
internal var didAppearCallback: (() -> Void)?
internal var willDisappearCallback: (() -> Void)?
internal var didDisappearCallback: (() -> Void)?
///
internal var animateLayer: CALayer?
internal var animation: CAAnimation?
internal var progressView: ProHUD.ProgressView?
///
internal var buttonEvents = [UIButton:() -> Void]()
init() {
super.init(nibName: nil, bundle: nil)
debug(self, "init")
}
required public init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
deinit {
debug("👌", self, "deinit")
}
override public func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
public override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
willAppearCallback?()
}
public override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
didAppearCallback?()
}
public override func viewDidDisappear(_ animated: Bool) {
super.viewDidDisappear(animated)
didDisappearCallback?()
}
public func viewWillAppear(_ callback: (() -> Void)?) {
willAppearCallback = callback
}
public func viewDidAppear(_ callback: (() -> Void)?) {
didAppearCallback = callback
}
public func viewWillDisappear(_ callback: (() -> Void)?) {
willDisappearCallback = callback
}
public func viewDidDisappear(_ callback: (() -> Void)?) {
didDisappearCallback = callback
}
}
// MARK: -
internal extension HUDController {
func addTouchUpAction(for button: UIButton, action: @escaping () -> Void) {
button.addTarget(self, action: #selector(didTappedButton(_:)), for: .touchUpInside)
buttonEvents[button] = action
}
@objc func didTappedButton(_ sender: UIButton) {
if let ac = buttonEvents[sender] {
ac()
}
}
}
// MARK: -
///
public protocol LoadingAnimationView: HUDController {
var imageView: UIImageView { get }
}
public extension LoadingAnimationView {
/// updateProgress(0)
/// - Parameter progress: 0~1
func update(progress: CGFloat) {
if let spv = imageView.superview {
if progressView == nil {
let v = ProHUD.ProgressView()
spv.addSubview(v)
v.snp.makeConstraints { (mk) in
mk.center.equalTo(imageView)
mk.width.height.equalTo(28)
}
progressView = v
}
if let v = progressView {
v.updateProgress(progress: progress)
}
}
}
}
///
public protocol LoadingRotateAnimation: LoadingAnimationView {}
public extension LoadingRotateAnimation {
///
/// - Parameters:
/// - layer:
/// - direction:
/// - speed:
func startRotate(_ layer: CALayer? = nil, direction: ProHUD.RotateDirection = .clockwise, speed: CFTimeInterval = 2) {
DispatchQueue.main.async {
let l = layer ?? self.imageView.layer
self.animateLayer = l
l.startRotate(direction: direction, speed: speed)
NotificationCenter.default.addObserver(self, selector: #selector(self.didEnterBackground), name: UIApplication.didEnterBackgroundNotification, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(self.willEnterForeground), name: UIApplication.willEnterForegroundNotification, object: nil)
}
}
///
/// - Parameter layer:
func endRotate(_ layer: CALayer? = nil) {
DispatchQueue.main.async {
self.animateLayer = nil
(layer ?? self.imageView.layer)?.endRotate()
NotificationCenter.default.removeObserver(self, name: UIApplication.didEnterBackgroundNotification, object: nil)
NotificationCenter.default.removeObserver(self, name: UIApplication.willEnterForegroundNotification, object: nil)
}
}
}
///
extension HUDController {
@objc func didEnterBackground() {
if let layer = animateLayer {
animation = layer.animation(forKey: .rotateKey)
layer.timeOffset = layer.convertTime(CACurrentMediaTime(), from: nil)
layer.speed = 0
}
}
@objc func willEnterForeground() {
if let layer = animateLayer, let ani = animation, layer.speed == 0 {
let pauseTime = layer.timeOffset
layer.timeOffset = 0
let beginTime = layer.convertTime(CACurrentMediaTime(), from: nil) - pauseTime
layer.beginTime = beginTime
layer.speed = 1
layer.add(ani, forKey: .rotateKey)
}
}
}