mirror of https://github.com/xaoxuu/ProHUD
优化代码
This commit is contained in:
parent
570d3969be
commit
0d60632592
|
@ -35,12 +35,12 @@ class TestAlertVC: BaseListVC {
|
||||||
func f() {
|
func f() {
|
||||||
Alert.push(scene: .loading, title: "正在同步", message: "请稍等片刻") { (a) in
|
Alert.push(scene: .loading, title: "正在同步", message: "请稍等片刻") { (a) in
|
||||||
a.identifier = "loading"
|
a.identifier = "loading"
|
||||||
a.rotate()
|
a.startRotate()
|
||||||
a.didForceQuit {
|
a.didForceQuit {
|
||||||
let t = Toast.push(scene: .loading, title: "正在同步", message: "请稍等片刻(点击展开为Alert)") { (vm) in
|
let t = Toast.push(scene: .loading, title: "正在同步", message: "请稍等片刻(点击展开为Alert)") { (vm) in
|
||||||
vm.identifier = "loading"
|
vm.identifier = "loading"
|
||||||
}
|
}
|
||||||
t.rotate()
|
t.startRotate()
|
||||||
t.didTapped { [weak t] in
|
t.didTapped { [weak t] in
|
||||||
t?.pop()
|
t?.pop()
|
||||||
f()
|
f()
|
||||||
|
@ -52,7 +52,7 @@ class TestAlertVC: BaseListVC {
|
||||||
} else if row == 1 {
|
} else if row == 1 {
|
||||||
Alert.push() { (a) in
|
Alert.push() { (a) in
|
||||||
a.identifier = "loading"
|
a.identifier = "loading"
|
||||||
a.rotate()
|
a.startRotate()
|
||||||
a.update { (vm) in
|
a.update { (vm) in
|
||||||
vm.scene = .loading
|
vm.scene = .loading
|
||||||
vm.title = "正在同步"
|
vm.title = "正在同步"
|
||||||
|
@ -72,7 +72,7 @@ class TestAlertVC: BaseListVC {
|
||||||
let a = Alert.push() { (a) in
|
let a = Alert.push() { (a) in
|
||||||
a.identifier = "loading"
|
a.identifier = "loading"
|
||||||
}
|
}
|
||||||
a.rotate()
|
a.startRotate()
|
||||||
a.update { (vm) in
|
a.update { (vm) in
|
||||||
vm.scene = .loading
|
vm.scene = .loading
|
||||||
vm.title = "正在同步"
|
vm.title = "正在同步"
|
||||||
|
@ -99,7 +99,7 @@ class TestAlertVC: BaseListVC {
|
||||||
vm.message = "请稍等片刻"
|
vm.message = "请稍等片刻"
|
||||||
vm.remove(action: 0, 1)
|
vm.remove(action: 0, 1)
|
||||||
}
|
}
|
||||||
a.rotate()
|
a.startRotate()
|
||||||
DispatchQueue.main.asyncAfter(deadline: .now()+2) {
|
DispatchQueue.main.asyncAfter(deadline: .now()+2) {
|
||||||
a.update { (vm) in
|
a.update { (vm) in
|
||||||
vm.scene = .error
|
vm.scene = .error
|
||||||
|
@ -138,7 +138,7 @@ class TestAlertVC: BaseListVC {
|
||||||
vm.scene = .loading
|
vm.scene = .loading
|
||||||
vm.title = "正在加载"
|
vm.title = "正在加载"
|
||||||
}
|
}
|
||||||
a.rotate()
|
a.startRotate()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -161,7 +161,7 @@ class TestAlertVC: BaseListVC {
|
||||||
} else if row == 5 {
|
} else if row == 5 {
|
||||||
func f(_ i: Int) {
|
func f(_ i: Int) {
|
||||||
Alert.push() { (a) in
|
Alert.push() { (a) in
|
||||||
a.rotate()
|
a.startRotate()
|
||||||
a.update { (vm) in
|
a.update { (vm) in
|
||||||
vm.scene = .loading
|
vm.scene = .loading
|
||||||
vm.title = "正在同步" + String(i)
|
vm.title = "正在同步" + String(i)
|
||||||
|
|
|
@ -65,7 +65,7 @@ class TestGuardVC: BaseListVC {
|
||||||
vm.message = "请稍等片刻"
|
vm.message = "请稍等片刻"
|
||||||
vm.remove(action: 0, 1)
|
vm.remove(action: 0, 1)
|
||||||
})
|
})
|
||||||
vc?.rotate()
|
vc?.startRotate()
|
||||||
DispatchQueue.main.asyncAfter(deadline: .now()+1) {
|
DispatchQueue.main.asyncAfter(deadline: .now()+1) {
|
||||||
vc?.update({ (vm) in
|
vc?.update({ (vm) in
|
||||||
vm.scene = .success
|
vm.scene = .success
|
||||||
|
|
|
@ -40,7 +40,7 @@ class TestToastVC: BaseListVC {
|
||||||
if row == 0 {
|
if row == 0 {
|
||||||
Toast.push(scene: .loading, title: "正在同步", message: "请稍等片刻") { (vm) in
|
Toast.push(scene: .loading, title: "正在同步", message: "请稍等片刻") { (vm) in
|
||||||
vm.identifier = "loading"
|
vm.identifier = "loading"
|
||||||
}.rotate()
|
}.startRotate()
|
||||||
simulateSync()
|
simulateSync()
|
||||||
} else if row == 1 {
|
} else if row == 1 {
|
||||||
let t = Toast.push(scene: .success, title: "同步成功", message: "点击查看详情")
|
let t = Toast.push(scene: .success, title: "同步成功", message: "点击查看详情")
|
||||||
|
@ -163,7 +163,7 @@ class TestToastVC: BaseListVC {
|
||||||
mk.center.equalToSuperview()
|
mk.center.equalToSuperview()
|
||||||
mk.width.height.equalTo(18)
|
mk.width.height.equalTo(18)
|
||||||
}
|
}
|
||||||
t.rotate(imgv.layer, speed: 4)
|
t.startRotate(imgv.layer, speed: 4)
|
||||||
}
|
}
|
||||||
simulateSync()
|
simulateSync()
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
CDC39CFD22FD6DDF0070E914 /* GuardModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = CDC39CFC22FD6DDF0070E914 /* GuardModel.swift */; };
|
CDC39CFD22FD6DDF0070E914 /* GuardModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = CDC39CFC22FD6DDF0070E914 /* GuardModel.swift */; };
|
||||||
CDC67BE92490A19100CC6FE6 /* SnapKit in Frameworks */ = {isa = PBXBuildFile; productRef = CDC67BE82490A19100CC6FE6 /* SnapKit */; };
|
CDC67BE92490A19100CC6FE6 /* SnapKit in Frameworks */ = {isa = PBXBuildFile; productRef = CDC67BE82490A19100CC6FE6 /* SnapKit */; };
|
||||||
CDC67BEC2490A1D100CC6FE6 /* Inspire in Frameworks */ = {isa = PBXBuildFile; productRef = CDC67BEB2490A1D100CC6FE6 /* Inspire */; };
|
CDC67BEC2490A1D100CC6FE6 /* Inspire in Frameworks */ = {isa = PBXBuildFile; productRef = CDC67BEB2490A1D100CC6FE6 /* Inspire */; };
|
||||||
|
CDF2C58924A0572C002ECDD5 /* HUDUtils.swift in Sources */ = {isa = PBXBuildFile; fileRef = CDF2C58824A0572C002ECDD5 /* HUDUtils.swift */; };
|
||||||
/* End PBXBuildFile section */
|
/* End PBXBuildFile section */
|
||||||
|
|
||||||
/* Begin PBXFileReference section */
|
/* Begin PBXFileReference section */
|
||||||
|
@ -47,6 +48,7 @@
|
||||||
CDB6A07A22EEF06500AF6CF0 /* HUDController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HUDController.swift; sourceTree = "<group>"; };
|
CDB6A07A22EEF06500AF6CF0 /* HUDController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HUDController.swift; sourceTree = "<group>"; };
|
||||||
CDB6A07C22EEF19D00AF6CF0 /* HUDConfig.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HUDConfig.swift; sourceTree = "<group>"; };
|
CDB6A07C22EEF19D00AF6CF0 /* HUDConfig.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HUDConfig.swift; sourceTree = "<group>"; };
|
||||||
CDC39CFC22FD6DDF0070E914 /* GuardModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GuardModel.swift; sourceTree = "<group>"; };
|
CDC39CFC22FD6DDF0070E914 /* GuardModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GuardModel.swift; sourceTree = "<group>"; };
|
||||||
|
CDF2C58824A0572C002ECDD5 /* HUDUtils.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HUDUtils.swift; sourceTree = "<group>"; };
|
||||||
DC31EBFAC56868D6096A233A /* Pods-ProHUD.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ProHUD.release.xcconfig"; path = "Pods/Target Support Files/Pods-ProHUD/Pods-ProHUD.release.xcconfig"; sourceTree = "<group>"; };
|
DC31EBFAC56868D6096A233A /* Pods-ProHUD.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ProHUD.release.xcconfig"; path = "Pods/Target Support Files/Pods-ProHUD/Pods-ProHUD.release.xcconfig"; sourceTree = "<group>"; };
|
||||||
/* End PBXFileReference section */
|
/* End PBXFileReference section */
|
||||||
|
|
||||||
|
@ -147,6 +149,7 @@
|
||||||
CDB6A07C22EEF19D00AF6CF0 /* HUDConfig.swift */,
|
CDB6A07C22EEF19D00AF6CF0 /* HUDConfig.swift */,
|
||||||
CDB6A07A22EEF06500AF6CF0 /* HUDController.swift */,
|
CDB6A07A22EEF06500AF6CF0 /* HUDController.swift */,
|
||||||
CD16491122EF0D900077988C /* HUDView.swift */,
|
CD16491122EF0D900077988C /* HUDView.swift */,
|
||||||
|
CDF2C58824A0572C002ECDD5 /* HUDUtils.swift */,
|
||||||
CD6CD87322F185B400F4FD4A /* Toast */,
|
CD6CD87322F185B400F4FD4A /* Toast */,
|
||||||
CD16491022EF0A4B0077988C /* Alert */,
|
CD16491022EF0A4B0077988C /* Alert */,
|
||||||
CD6CD87C22F185DA00F4FD4A /* Guard */,
|
CD6CD87C22F185DA00F4FD4A /* Guard */,
|
||||||
|
@ -280,6 +283,7 @@
|
||||||
CD6CD86C22F1858F00F4FD4A /* ToastModel.swift in Sources */,
|
CD6CD86C22F1858F00F4FD4A /* ToastModel.swift in Sources */,
|
||||||
CD16490B22EF09AB0077988C /* AlertModel.swift in Sources */,
|
CD16490B22EF09AB0077988C /* AlertModel.swift in Sources */,
|
||||||
CD16491222EF0D900077988C /* HUDView.swift in Sources */,
|
CD16491222EF0D900077988C /* HUDView.swift in Sources */,
|
||||||
|
CDF2C58924A0572C002ECDD5 /* HUDUtils.swift in Sources */,
|
||||||
CDB6A07B22EEF06500AF6CF0 /* HUDController.swift in Sources */,
|
CDB6A07B22EEF06500AF6CF0 /* HUDController.swift in Sources */,
|
||||||
CDC39CFD22FD6DDF0070E914 /* GuardModel.swift in Sources */,
|
CDC39CFD22FD6DDF0070E914 /* GuardModel.swift in Sources */,
|
||||||
);
|
);
|
||||||
|
|
|
@ -65,8 +65,8 @@ public extension ProHUD.Configuration {
|
||||||
|
|
||||||
/// 加载强制退出按钮
|
/// 加载强制退出按钮
|
||||||
/// - Parameter callback: 回调代码
|
/// - Parameter callback: 回调代码
|
||||||
public func loadForceQuitButton(_ callback: @escaping (ProHUD.Alert) -> Void) {
|
public func loadHideButton(_ callback: @escaping (ProHUD.Alert) -> Void) {
|
||||||
privLoadForceQuitButton = callback
|
privLoadHideButton = callback
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -234,11 +234,11 @@ fileprivate var privUpdateActionStack: (ProHUD.Alert) -> Void = {
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
fileprivate var privLoadForceQuitButton: (ProHUD.Alert) -> Void = {
|
fileprivate var privLoadHideButton: (ProHUD.Alert) -> Void = {
|
||||||
return { (vc) in
|
return { (vc) in
|
||||||
debug(vc, "showNavButtons")
|
debug(vc, "showNavButtons")
|
||||||
let config = cfg.alert
|
let config = cfg.alert
|
||||||
let btn = ProHUD.Alert.Button.forceQuitButton()
|
let btn = ProHUD.Alert.Button.createHideButton()
|
||||||
btn.setTitle(cfg.alert.forceQuitTitle, for: .normal)
|
btn.setTitle(cfg.alert.forceQuitTitle, for: .normal)
|
||||||
let bg = createBlurView()
|
let bg = createBlurView()
|
||||||
bg.layer.masksToBounds = true
|
bg.layer.masksToBounds = true
|
||||||
|
@ -312,19 +312,19 @@ fileprivate var privReloadData: (ProHUD.Alert) -> Void = {
|
||||||
// 设置持续时间
|
// 设置持续时间
|
||||||
vc.vm.updateDuration()
|
vc.vm.updateDuration()
|
||||||
|
|
||||||
// 强制退出按钮
|
// 「隐藏」按钮出现的时间
|
||||||
vc.vm.forceQuitTimerBlock?.cancel()
|
vc.vm.hideTimerBlock?.cancel()
|
||||||
if vc.buttonEvents.count == 0 {
|
if vc.buttonEvents.count == 0 {
|
||||||
vc.vm.forceQuitTimerBlock = DispatchWorkItem(block: { [weak vc] in
|
vc.vm.hideTimerBlock = DispatchWorkItem(block: { [weak vc] in
|
||||||
if let vc = vc {
|
if let vc = vc {
|
||||||
if vc.buttonEvents.count == 0 {
|
if vc.buttonEvents.count == 0 {
|
||||||
privLoadForceQuitButton(vc)
|
privLoadHideButton(vc)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
DispatchQueue.main.asyncAfter(deadline: .now() + config.forceQuitTimer, execute: vc.vm.forceQuitTimerBlock!)
|
DispatchQueue.main.asyncAfter(deadline: .now() + config.forceQuitTimer, execute: vc.vm.hideTimerBlock!)
|
||||||
} else {
|
} else {
|
||||||
vc.vm.forceQuitTimerBlock = nil
|
vc.vm.hideTimerBlock = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -90,6 +90,7 @@ public extension Alert {
|
||||||
/// 推入屏幕
|
/// 推入屏幕
|
||||||
@discardableResult func push() -> Alert {
|
@discardableResult func push() -> Alert {
|
||||||
if Alert.alerts.contains(self) == false {
|
if Alert.alerts.contains(self) == false {
|
||||||
|
willAppearCallback?()
|
||||||
let window = Alert.privGetAlertWindow(self)
|
let window = Alert.privGetAlertWindow(self)
|
||||||
window.makeKeyAndVisible()
|
window.makeKeyAndVisible()
|
||||||
window.resignKey()
|
window.resignKey()
|
||||||
|
@ -107,6 +108,7 @@ public extension Alert {
|
||||||
window.backgroundColor = window.backgroundColor?.withAlphaComponent(0.6)
|
window.backgroundColor = window.backgroundColor?.withAlphaComponent(0.6)
|
||||||
}
|
}
|
||||||
Alert.alerts.append(self)
|
Alert.alerts.append(self)
|
||||||
|
didAppearCallback?()
|
||||||
}
|
}
|
||||||
Alert.privUpdateAlertsLayout()
|
Alert.privUpdateAlertsLayout()
|
||||||
return self
|
return self
|
||||||
|
@ -123,6 +125,7 @@ public extension Alert {
|
||||||
}) { (done) in
|
}) { (done) in
|
||||||
self.view.removeFromSuperview()
|
self.view.removeFromSuperview()
|
||||||
self.removeFromParent()
|
self.removeFromParent()
|
||||||
|
self.didDisappearCallback?()
|
||||||
}
|
}
|
||||||
// hide window
|
// hide window
|
||||||
let count = Alert.alerts.count
|
let count = Alert.alerts.count
|
||||||
|
@ -153,9 +156,9 @@ public extension Alert {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
extension Alert: RotateAnimation {
|
|
||||||
|
|
||||||
}
|
// MARK: 支持加载动画
|
||||||
|
extension Alert: LoadingRotateAnimation {}
|
||||||
|
|
||||||
// MARK: - 实例管理器
|
// MARK: - 实例管理器
|
||||||
public extension Alert {
|
public extension Alert {
|
||||||
|
@ -218,7 +221,7 @@ internal extension Alert {
|
||||||
/// - Parameter title: 标题
|
/// - Parameter title: 标题
|
||||||
/// - Parameter action: 事件
|
/// - Parameter action: 事件
|
||||||
@discardableResult func insert(action index: Int?, style: UIAlertAction.Style, title: String?, handler: (() -> Void)?) -> UIButton {
|
@discardableResult func insert(action index: Int?, style: UIAlertAction.Style, title: String?, handler: (() -> Void)?) -> UIButton {
|
||||||
let btn = Button.actionButton(title: title)
|
let btn = Button.createActionButton(title: title)
|
||||||
if let idx = index, idx < actionStack.arrangedSubviews.count {
|
if let idx = index, idx < actionStack.arrangedSubviews.count {
|
||||||
actionStack.insertArrangedSubview(btn, at: idx)
|
actionStack.insertArrangedSubview(btn, at: idx)
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -50,7 +50,7 @@ public extension Alert {
|
||||||
internal var durationBlock: DispatchWorkItem?
|
internal var durationBlock: DispatchWorkItem?
|
||||||
|
|
||||||
/// 强制退出按钮
|
/// 强制退出按钮
|
||||||
internal var forceQuitTimerBlock: DispatchWorkItem?
|
internal var hideTimerBlock: DispatchWorkItem?
|
||||||
|
|
||||||
/// 强制退出代码
|
/// 强制退出代码
|
||||||
internal var forceQuitCallback: (() -> Void)?
|
internal var forceQuitCallback: (() -> Void)?
|
||||||
|
|
|
@ -99,6 +99,7 @@ public extension Guard {
|
||||||
/// - Parameter viewController: 视图控制器
|
/// - Parameter viewController: 视图控制器
|
||||||
@discardableResult func push(to viewController: UIViewController? = nil) -> Guard {
|
@discardableResult func push(to viewController: UIViewController? = nil) -> Guard {
|
||||||
func f(_ vc: UIViewController) -> Guard {
|
func f(_ vc: UIViewController) -> Guard {
|
||||||
|
willAppearCallback?()
|
||||||
view.layoutIfNeeded()
|
view.layoutIfNeeded()
|
||||||
vc.addChild(self)
|
vc.addChild(self)
|
||||||
vc.view.addSubview(view)
|
vc.view.addSubview(view)
|
||||||
|
@ -113,6 +114,7 @@ public extension Guard {
|
||||||
UIView.animateForGuard {
|
UIView.animateForGuard {
|
||||||
self.privTranslateIn()
|
self.privTranslateIn()
|
||||||
}
|
}
|
||||||
|
didAppearCallback?()
|
||||||
return self
|
return self
|
||||||
}
|
}
|
||||||
if let vc = viewController ?? cfg.rootViewController {
|
if let vc = viewController ?? cfg.rootViewController {
|
||||||
|
@ -150,6 +152,7 @@ public extension Guard {
|
||||||
}) { (done) in
|
}) { (done) in
|
||||||
if self.isDisplaying == false {
|
if self.isDisplaying == false {
|
||||||
self.view.removeFromSuperview()
|
self.view.removeFromSuperview()
|
||||||
|
self.didDisappearCallback?()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -285,7 +288,7 @@ internal extension Guard {
|
||||||
/// - Parameter title: 标题
|
/// - Parameter title: 标题
|
||||||
/// - Parameter action: 事件
|
/// - Parameter action: 事件
|
||||||
@discardableResult func insert(action index: Int?, style: UIAlertAction.Style, title: String?, handler: (() -> Void)?) -> UIButton {
|
@discardableResult func insert(action index: Int?, style: UIAlertAction.Style, title: String?, handler: (() -> Void)?) -> UIButton {
|
||||||
let btn = Button.actionButton(title: title)
|
let btn = Button.createActionButton(title: title)
|
||||||
btn.titleLabel?.font = cfg.guard.buttonFont
|
btn.titleLabel?.font = cfg.guard.buttonFont
|
||||||
if let idx = index, idx < actionStack.arrangedSubviews.count {
|
if let idx = index, idx < actionStack.arrangedSubviews.count {
|
||||||
actionStack.insertArrangedSubview(btn, at: idx)
|
actionStack.insertArrangedSubview(btn, at: idx)
|
||||||
|
|
|
@ -19,7 +19,7 @@ public class HUDController: UIViewController {
|
||||||
internal var didDisappearCallback: (() -> Void)?
|
internal var didDisappearCallback: (() -> Void)?
|
||||||
|
|
||||||
/// 执行动画的图层
|
/// 执行动画的图层
|
||||||
public var animateLayer: CALayer?
|
var animateLayer: CALayer?
|
||||||
internal var animation: CAAnimation?
|
internal var animation: CAAnimation?
|
||||||
|
|
||||||
/// 按钮事件
|
/// 按钮事件
|
||||||
|
@ -74,6 +74,7 @@ public class HUDController: UIViewController {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MARK: - 事件
|
||||||
internal extension HUDController {
|
internal extension HUDController {
|
||||||
|
|
||||||
func addTouchUpAction(for button: UIButton, action: @escaping () -> Void) {
|
func addTouchUpAction(for button: UIButton, action: @escaping () -> Void) {
|
||||||
|
@ -89,15 +90,55 @@ internal extension HUDController {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MARK: - 动画
|
||||||
|
|
||||||
|
/// 图片动画
|
||||||
|
public protocol LoadingAnimationView: HUDController {
|
||||||
|
var imageView: UIImageView { get }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 旋转动画
|
||||||
|
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 {
|
extension HUDController {
|
||||||
@objc func pauseAnimation() {
|
@objc func didEnterBackground() {
|
||||||
if let layer = animateLayer {
|
if let layer = animateLayer {
|
||||||
animation = layer.animation(forKey: .rotateKey)
|
animation = layer.animation(forKey: .rotateKey)
|
||||||
layer.timeOffset = layer.convertTime(CACurrentMediaTime(), from: nil)
|
layer.timeOffset = layer.convertTime(CACurrentMediaTime(), from: nil)
|
||||||
layer.speed = 0
|
layer.speed = 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@objc func resumeAnimation() {
|
@objc func willEnterForeground() {
|
||||||
if let layer = animateLayer, let ani = animation, layer.speed == 0 {
|
if let layer = animateLayer, let ani = animation, layer.speed == 0 {
|
||||||
let pauseTime = layer.timeOffset
|
let pauseTime = layer.timeOffset
|
||||||
layer.timeOffset = 0
|
layer.timeOffset = 0
|
||||||
|
@ -109,29 +150,3 @@ extension HUDController {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public protocol RotateAnimation: HUDController {
|
|
||||||
var imageView: UIImageView { get }
|
|
||||||
var animateLayer: CALayer? { get set }
|
|
||||||
}
|
|
||||||
|
|
||||||
public extension RotateAnimation {
|
|
||||||
|
|
||||||
func rotate(_ 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.pauseAnimation), name: UIApplication.didEnterBackgroundNotification, object: nil)
|
|
||||||
NotificationCenter.default.addObserver(self, selector: #selector(self.resumeAnimation), name: UIApplication.willEnterForegroundNotification, object: nil)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
func rotate(_ layer: CALayer? = nil, _ flag: Bool) {
|
|
||||||
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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
|
@ -0,0 +1,20 @@
|
||||||
|
//
|
||||||
|
// HUDUtils.swift
|
||||||
|
// ProHUD
|
||||||
|
//
|
||||||
|
// Created by xaoxuu on 2020/6/22.
|
||||||
|
// Copyright © 2020 Titan Studio. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import UIKit
|
||||||
|
import Inspire
|
||||||
|
|
||||||
|
extension String {
|
||||||
|
static let rotateKey = "rotationAnimation"
|
||||||
|
}
|
||||||
|
|
||||||
|
extension ProHUD {
|
||||||
|
static var safeAreaInsets: UIEdgeInsets {
|
||||||
|
return Inspire.shared.screen.updatedSafeAreaInsets
|
||||||
|
}
|
||||||
|
}
|
|
@ -7,10 +7,12 @@
|
||||||
//
|
//
|
||||||
|
|
||||||
import UIKit
|
import UIKit
|
||||||
import Inspire
|
|
||||||
|
// MARK: - public
|
||||||
|
|
||||||
public extension ProHUD {
|
public extension ProHUD {
|
||||||
|
|
||||||
|
/// 堆栈视图容器
|
||||||
class StackContainer: UIStackView {
|
class StackContainer: UIStackView {
|
||||||
|
|
||||||
public override init(frame: CGRect) {
|
public override init(frame: CGRect) {
|
||||||
|
@ -27,21 +29,29 @@ public extension ProHUD {
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 旋转方向
|
/// 旋转方向
|
||||||
enum RotateDirection: Double {
|
enum RotateDirection: Double {
|
||||||
|
/// 顺时针
|
||||||
case clockwise = 1
|
case clockwise = 1
|
||||||
|
/// 逆时针
|
||||||
case counterclockwise = -1
|
case counterclockwise = -1
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal extension String {
|
// MARK: - internal
|
||||||
static let rotateKey = "rotationAnimation"
|
|
||||||
}
|
|
||||||
|
|
||||||
|
// MARK: 弹窗
|
||||||
internal extension Alert {
|
internal extension Alert {
|
||||||
|
|
||||||
|
/// 弹窗的按钮
|
||||||
class Button: UIButton {
|
class Button: UIButton {
|
||||||
class func actionButton(title: String?) -> Button {
|
|
||||||
|
/// 创建操作按钮
|
||||||
|
/// - Parameter title: 标题
|
||||||
|
/// - Returns: 按钮
|
||||||
|
static func createActionButton(title: String?) -> Button {
|
||||||
let btn = Button(type: .system)
|
let btn = Button(type: .system)
|
||||||
btn.setTitle(title, for: .normal)
|
btn.setTitle(title, for: .normal)
|
||||||
btn.layer.cornerRadius = cfg.alert.cornerRadius / 2
|
btn.layer.cornerRadius = cfg.alert.cornerRadius / 2
|
||||||
|
@ -49,6 +59,8 @@ internal extension Alert {
|
||||||
return btn
|
return btn
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// 更新按钮
|
||||||
|
/// - Parameter style: 样式
|
||||||
func update(style: UIAlertAction.Style) {
|
func update(style: UIAlertAction.Style) {
|
||||||
let pd = CGFloat(8)
|
let pd = CGFloat(8)
|
||||||
if style != .cancel {
|
if style != .cancel {
|
||||||
|
@ -71,7 +83,9 @@ internal extension Alert {
|
||||||
tag = style.rawValue
|
tag = style.rawValue
|
||||||
}
|
}
|
||||||
|
|
||||||
class func forceQuitButton() -> UIButton {
|
/// 创建隐藏按钮
|
||||||
|
/// - Returns: 按钮
|
||||||
|
static func createHideButton() -> UIButton {
|
||||||
let btn = Button(type: .system)
|
let btn = Button(type: .system)
|
||||||
let pd = cfg.alert.padding/2
|
let pd = cfg.alert.padding/2
|
||||||
btn.contentEdgeInsets = .init(top: pd*1.5, left: pd*1.5, bottom: pd*1.5, right: pd*1.5)
|
btn.contentEdgeInsets = .init(top: pd*1.5, left: pd*1.5, bottom: pd*1.5, right: pd*1.5)
|
||||||
|
@ -85,10 +99,16 @@ internal extension Alert {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MARK: 操作表
|
||||||
internal extension Guard {
|
internal extension Guard {
|
||||||
|
|
||||||
|
/// 操作表的按钮
|
||||||
class Button: UIButton {
|
class Button: UIButton {
|
||||||
class func actionButton(title: String?) -> Button {
|
|
||||||
|
/// 创建操作按钮
|
||||||
|
/// - Parameter title: 标题
|
||||||
|
/// - Returns: 按钮
|
||||||
|
static func createActionButton(title: String?) -> Button {
|
||||||
let btn = Button(type: .system)
|
let btn = Button(type: .system)
|
||||||
btn.setTitle(title, for: .normal)
|
btn.setTitle(title, for: .normal)
|
||||||
btn.layer.cornerRadius = cfg.guard.buttonCornerRadius
|
btn.layer.cornerRadius = cfg.guard.buttonCornerRadius
|
||||||
|
@ -122,6 +142,8 @@ internal extension Guard {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MARK: - 动画
|
||||||
|
|
||||||
internal extension UIView {
|
internal extension UIView {
|
||||||
|
|
||||||
private class func animateEaseOut(duration: TimeInterval = 1, delay: TimeInterval = 0, animations: @escaping () -> Void, completion: ((Bool) -> Void)? = nil) {
|
private class func animateEaseOut(duration: TimeInterval = 1, delay: TimeInterval = 0, animations: @escaping () -> Void, completion: ((Bool) -> Void)? = nil) {
|
||||||
|
@ -158,7 +180,13 @@ internal extension UIView {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
extension CALayer {
|
extension CALayer {
|
||||||
|
|
||||||
|
/// 开始旋转
|
||||||
|
/// - Parameters:
|
||||||
|
/// - direction: 方向
|
||||||
|
/// - speed: 速度
|
||||||
func startRotate(direction: ProHUD.RotateDirection, speed: CFTimeInterval) {
|
func startRotate(direction: ProHUD.RotateDirection, speed: CFTimeInterval) {
|
||||||
if animation(forKey: .rotateKey) == nil {
|
if animation(forKey: .rotateKey) == nil {
|
||||||
let ani = CABasicAnimation(keyPath: "transform.rotation.z")
|
let ani = CABasicAnimation(keyPath: "transform.rotation.z")
|
||||||
|
@ -170,13 +198,10 @@ extension CALayer {
|
||||||
add(ani, forKey: .rotateKey)
|
add(ani, forKey: .rotateKey)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// 结束旋转
|
||||||
func endRotate() {
|
func endRotate() {
|
||||||
removeAnimation(forKey: .rotateKey)
|
removeAnimation(forKey: .rotateKey)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
extension ProHUD {
|
|
||||||
static var safeAreaInsets: UIEdgeInsets {
|
|
||||||
return Inspire.shared.screen.updatedSafeAreaInsets
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -116,6 +116,7 @@ public extension Toast {
|
||||||
let config = cfg.toast
|
let config = cfg.toast
|
||||||
let isNew: Bool
|
let isNew: Bool
|
||||||
if self.window == nil {
|
if self.window == nil {
|
||||||
|
willAppearCallback?()
|
||||||
let window = UIWindow(frame: .zero)
|
let window = UIWindow(frame: .zero)
|
||||||
self.window = window
|
self.window = window
|
||||||
if #available(iOS 13.0, *) {
|
if #available(iOS 13.0, *) {
|
||||||
|
@ -166,6 +167,7 @@ public extension Toast {
|
||||||
} else {
|
} else {
|
||||||
view.layoutIfNeeded()
|
view.layoutIfNeeded()
|
||||||
}
|
}
|
||||||
|
didAppearCallback?()
|
||||||
return self
|
return self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -205,9 +207,8 @@ public extension Toast {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
extension Toast: RotateAnimation {
|
// MARK: 支持加载动画
|
||||||
|
extension Toast: LoadingRotateAnimation {}
|
||||||
}
|
|
||||||
|
|
||||||
// MARK: - 实例管理器
|
// MARK: - 实例管理器
|
||||||
public extension Toast {
|
public extension Toast {
|
||||||
|
@ -267,6 +268,7 @@ public extension Toast {
|
||||||
toast.view.removeFromSuperview()
|
toast.view.removeFromSuperview()
|
||||||
toast.removeFromParent()
|
toast.removeFromParent()
|
||||||
toast.window = nil
|
toast.window = nil
|
||||||
|
toast.didDisappearCallback?()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -288,6 +290,7 @@ fileprivate extension Toast {
|
||||||
/// 点击事件
|
/// 点击事件
|
||||||
/// - Parameter sender: 手势
|
/// - Parameter sender: 手势
|
||||||
@objc func privDidTapped(_ sender: UITapGestureRecognizer) {
|
@objc func privDidTapped(_ sender: UITapGestureRecognizer) {
|
||||||
|
pulse()
|
||||||
vm.tapCallback?()
|
vm.tapCallback?()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue