This commit is contained in:
xaoxuu 2019-08-05 14:20:52 +08:00
parent ff9805967a
commit 86b352bd44
7 changed files with 150 additions and 134 deletions

View File

@ -27,6 +27,28 @@ class ViewController: UIViewController {
} }
} }
@IBAction func test(_ sender: UIButton) {
// testUpdateAction()
testGuard()
}
func testDelete() {
let a = ProHUD.push(alert: .delete, title: "确认删除", message: "此操作不可撤销")
a.add(action: .destructive, title: "确认", action: { [weak a] in
a?.remove(action: 0, 1)
a?.update(scene: .loading, title: "正在删除", message: "请稍后片刻")
DispatchQueue.main.asyncAfter(deadline: .now()+1) {
a?.update(scene: .success, title: "删除成功", message: "啊哈哈哈哈").duration(2)
ProHUD.push(toast: .success, title: "删除成功", message: "aaa")
}
}).add(action: .cancel, title: "取消", action: nil)
}
func testToast() { func testToast() {
let t = ProHUD.Toast(scene: .loading, title: "正在加载", message: "请稍候片刻") let t = ProHUD.Toast(scene: .loading, title: "正在加载", message: "请稍候片刻")
@ -39,60 +61,42 @@ class ViewController: UIViewController {
let a2 = ProHUD.push(alert: .loading, title: "正在加载", message: "马上就要成功了") let a2 = ProHUD.push(alert: .loading, title: "正在加载", message: "马上就要成功了")
DispatchQueue.main.asyncAfter(deadline: .now()+1) { DispatchQueue.main.asyncAfter(deadline: .now()+1) {
let a3 = ProHUD.push(alert: .error, title: "加载失败", message: "点击充实") let a3 = ProHUD.push(alert: .error, title: "加载失败", message: "点击充实")
a3.addAction(style: .default, title: "重新加载") { [weak a3] in a3.add(action: .default, title: "重新加载") { [weak a3] in
a3?.updateContent(scene: .success, title: "加载成功", message: "马上就要成功了") a3?.update(scene: .success, title: "加载成功", message: "马上就要成功了")
a3?.updateAction(index: 0, style: .default, title: "OK", action: { [weak a2, a3] in a3?.update(action: 0, style: .default, title: "OK", action: { [weak a3] in
a2?.pop()
a3?.pop() a3?.pop()
}).removeAction(index: 1).removeAction(index: 1) }).remove(action: 1, 2)
}.addAction(style: .destructive, title: "终止", action: nil).addAction(style: .cancel, title: "取消", action: nil) }.add(action: .destructive, title: "终止", action: nil).add(action: .cancel, title: "取消", action: nil)
} }
} }
}
func testDelete() {
let a = ProHUD.push(alert: .delete, title: "确认删除", message: "此操作不可撤销")
a.addAction(style: .destructive, title: "确认", action: { [weak a] in
a?.removeAction(index: 0).removeAction(index: 0)
a?.updateContent(scene: .loading, title: "正在删除", message: "请稍后片刻")
DispatchQueue.main.asyncAfter(deadline: .now()+1) {
a?.updateContent(scene: .success, title: "删除成功", message: "啊哈哈哈哈").duration(2)
ProHUD.push(toast: .success, title: "删除成功", message: "aaa")
}
}).addAction(style: .cancel, title: "取消", action: nil)
} }
@IBAction func test(_ sender: UIButton) {
textUpdateAction()
}
func testGuard() { func testGuard() {
let g = ProHUD.Guard(title: "请求权限", message: "请打开相机权限开关,否则无法进行测量。") let g = ProHUD.Guard(title: "请求权限", message: "请打开相机权限开关,否则无法进行测量。")
g.loadTitle("呵呵") g.add(title: "呵呵")
g.loadBody("请打开相机权限开关,否则无法进行测量。请打开相机权限开关,否则无法进行测量。") g.add(message: "请打开相机权限开关,否则无法进行测量。请打开相机权限开关,否则无法进行测量。")
g.loadButton(style: .default, title: "测试弹窗", action: { [weak self] in g.add(action: .default, title: "测试弹窗", action: { [weak self] in
self?.testToast() self?.testToast()
}) })
g.loadButton(style: .destructive, title: "测试删除弹窗", action: { [weak self] in g.add(action: .destructive, title: "测试删除弹窗", action: { [weak self] in
self?.testDelete() self?.testDelete()
}) })
g.loadButton(style: .cancel, title: "我知道了") g.add(action: .cancel, title: "我知道了")
g.push(to: self) g.push(to: self)
debugPrint("test: ", g) debugPrint("test: ", g)
} }
func textUpdateAction() { func testUpdateAction() {
let a = ProHUD.push(alert: .confirm, title: "确认删除", message: "此操作无法撤销") let a = ProHUD.push(alert: .confirm, title: "确认删除", message: "此操作无法撤销")
a.addAction(style: .destructive, title: "删除") { a.add(action: .destructive, title: "删除") {
a.removeAction(index: 0, 1).updateContent(scene: .loading, title: "正在删除", message: "请稍后片刻") a.remove(action: 0, 1).update(scene: .loading, title: "正在删除", message: "请稍后片刻")
}.addAction(style: .cancel, title: "取消", action: nil) }.add(action: .cancel, title: "取消", action: nil)

View File

@ -75,11 +75,6 @@ public extension ProHUD {
} }
public override func viewDidDisappear(_ animated: Bool) {
super.viewDidDisappear(animated)
disappearCallback?()
}
} }
@ -121,19 +116,11 @@ public extension ProHUD.Alert {
// MARK: // MARK:
///
/// - Parameter duration:
@discardableResult func duration(_ duration: TimeInterval?) -> ProHUD.Alert {
model.duration = duration
willLayoutSubviews()
return self
}
/// ///
/// - Parameter style: /// - Parameter style:
/// - Parameter text: /// - Parameter text:
/// - Parameter action: /// - Parameter action:
@discardableResult func addAction(style: UIAlertAction.Style, title: String?, action: (() -> Void)?) -> ProHUD.Alert { @discardableResult func add(action style: UIAlertAction.Style, title: String?, action: (() -> Void)?) -> ProHUD.Alert {
if let btn = privAddButton(custom: Button.actionButton(title: title), action: action) as? Button { if let btn = privAddButton(custom: Button.actionButton(title: title), action: action) as? Button {
btn.update(style: style) btn.update(style: style)
} }
@ -143,7 +130,7 @@ public extension ProHUD.Alert {
/// ///
/// - Parameter button: /// - Parameter button:
/// - Parameter action: /// - Parameter action:
@discardableResult func addAction(custom button: UIButton, action: (() -> Void)?) -> ProHUD.Alert { @discardableResult func add(button: UIButton, action: (() -> Void)?) -> ProHUD.Alert {
privAddButton(custom: button, action: action) privAddButton(custom: button, action: action)
return self return self
} }
@ -162,12 +149,29 @@ public extension ProHUD.Alert {
return self return self
} }
/// ///
/// - Parameter duration:
@discardableResult func duration(_ duration: TimeInterval?) -> ProHUD.Alert {
model.duration = duration
willLayoutSubviews()
return self
}
///
/// - Parameter scene:
/// - Parameter title: /// - Parameter title:
@discardableResult func updateContent(scene: Scene, title: String? = nil, message: String? = nil, icon: UIImage? = nil) -> ProHUD.Alert { /// - Parameter message:
@discardableResult func update(scene: Scene, title: String?, message: String?) -> ProHUD.Alert {
model.scene = scene
model.title = title model.title = title
model.message = message model.message = message
model.scene = scene cfg.alert.reloadData(self)
return self
}
///
/// - Parameter icon:
@discardableResult func update(icon: UIImage?) -> ProHUD.Alert {
model.icon = icon model.icon = icon
cfg.alert.reloadData(self) cfg.alert.reloadData(self)
return self return self
@ -178,8 +182,8 @@ public extension ProHUD.Alert {
/// - Parameter style: /// - Parameter style:
/// - Parameter title: /// - Parameter title:
/// - Parameter action: /// - Parameter action:
@discardableResult func updateAction(index: Int, style: UIAlertAction.Style, title: String?, action: (() -> Void)?) -> ProHUD.Alert { @discardableResult func update(action index: Int, style: UIAlertAction.Style, title: String?, action: (() -> Void)?) -> ProHUD.Alert {
return updateAction(index: index, button: { (btn) in return update(action: index, button: { (btn) in
btn.setTitle(title, for: .normal) btn.setTitle(title, for: .normal)
if let b = btn as? Button { if let b = btn as? Button {
b.update(style: style) b.update(style: style)
@ -192,7 +196,7 @@ public extension ProHUD.Alert {
/// - Parameter index: /// - Parameter index:
/// - Parameter button: /// - Parameter button:
/// - Parameter action: /// - Parameter action:
@discardableResult func updateAction(index: Int, button: (UIButton) -> Void, action: (() -> Void)? = nil) -> ProHUD.Alert { @discardableResult func update(action index: Int, button: (UIButton) -> Void, action: (() -> Void)? = nil) -> ProHUD.Alert {
if index < self.actionStack.arrangedSubviews.count, let btn = self.actionStack.arrangedSubviews[index] as? UIButton { if index < self.actionStack.arrangedSubviews.count, let btn = self.actionStack.arrangedSubviews[index] as? UIButton {
button(btn) button(btn)
if let ac = action { if let ac = action {
@ -207,7 +211,7 @@ public extension ProHUD.Alert {
/// ///
/// - Parameter index: /// - Parameter index:
@discardableResult func removeAction(index: Int...) -> ProHUD.Alert { @discardableResult func remove(action index: Int...) -> ProHUD.Alert {
for (i, idx) in index.enumerated() { for (i, idx) in index.enumerated() {
privRemoveAction(index: idx-i) privRemoveAction(index: idx-i)
} }
@ -250,8 +254,8 @@ public extension ProHUD {
/// - Parameter title: /// - Parameter title:
/// - Parameter message: /// - Parameter message:
/// - Parameter icon: /// - Parameter icon:
@discardableResult func push(alert scene: Alert.Scene, title: String? = nil, message: String? = nil, icon: UIImage? = nil) -> Alert { @discardableResult func push(alert scene: Alert.Scene, title: String? = nil, message: String? = nil) -> Alert {
return push(Alert(scene: scene, title: title, message: message, icon: icon)) return push(Alert(scene: scene, title: title, message: message))
} }
/// ///
@ -285,6 +289,7 @@ public extension ProHUD {
} }
} }
} }
} }
@ -303,8 +308,8 @@ public extension ProHUD {
/// - Parameter title: /// - Parameter title:
/// - Parameter message: /// - Parameter message:
/// - Parameter icon: /// - Parameter icon:
@discardableResult class func push(alert: Alert.Scene, title: String? = nil, message: String? = nil, icon: UIImage? = nil) -> Alert { @discardableResult class func push(alert: Alert.Scene, title: String? = nil, message: String? = nil) -> Alert {
return shared.push(alert: alert, title: title, message: message, icon: icon) return shared.push(alert: alert, title: title, message: message)
} }
/// ///
@ -354,35 +359,23 @@ fileprivate extension ProHUD.Alert {
} }
func willLayoutSubviews() { func willLayoutSubviews() {
willLayout?.cancel() model.setupWillLayout(duration: 0.001) { [weak self] in
model.durationBlock?.cancel()
model.forceQuitTimerBlock?.cancel()
willLayout = DispatchWorkItem(block: { [weak self] in
if let a = self { if let a = self {
// //
cfg.alert.loadSubviews(a) cfg.alert.loadSubviews(a)
cfg.alert.reloadData(a) cfg.alert.reloadData(a)
// //
if let t = a.model.duration, t > 0 { a.model.setupDuration(duration: a.model.duration) { [weak self] in
a.model.durationBlock = DispatchWorkItem(block: { [weak self] in self?.pop()
self?.pop()
})
DispatchQueue.main.asyncAfter(deadline: .now()+t, execute: a.model.durationBlock!)
} else {
a.model.durationBlock = nil
} }
// 退 // 退
if cfg.alert.forceQuitTimer > 0 && self?.actionStack.superview == nil { a.model.setupForceQuit(duration: cfg.alert.forceQuitTimer) { [weak self] in
a.model.forceQuitTimerBlock = DispatchWorkItem(block: { [weak self] in if let aa = self, aa.actionStack.superview == nil {
if let s = self { cfg.alert.loadForceQuitButton(aa)
cfg.alert.loadForceQuitButton(s) }
}
})
DispatchQueue.main.asyncAfter(deadline: .now()+cfg.alert.forceQuitTimer, execute: a.model.forceQuitTimerBlock!)
} }
} }
}) }
DispatchQueue.main.asyncAfter(deadline: .now()+0.001, execute: willLayout!)
} }
@discardableResult func privAddButton(custom button: UIButton, action: (() -> Void)?) -> UIButton { @discardableResult func privAddButton(custom button: UIButton, action: (() -> Void)?) -> UIButton {

View File

@ -78,12 +78,38 @@ public extension ProHUD.Alert {
/// 退 /// 退
internal var forceQuitCallback: (() -> Void)? internal var forceQuitCallback: (() -> Void)?
public init(title: String? = nil, message: String? = nil, icon: UIImage? = nil) { internal var willLayoutBlock: DispatchWorkItem?
self.title = title
self.message = message internal mutating func setupDuration(duration: TimeInterval?, callback: @escaping () -> Void) {
self.icon = icon self.duration = duration
durationBlock?.cancel()
if let t = duration, t > 0 {
durationBlock = DispatchWorkItem(block: callback)
DispatchQueue.main.asyncAfter(deadline: .now()+t, execute: durationBlock!)
} else {
durationBlock = nil
}
} }
internal mutating func setupForceQuit(duration: TimeInterval?, callback: @escaping () -> Void) {
forceQuitTimerBlock?.cancel()
if let t = duration, t > 0 {
forceQuitTimerBlock = DispatchWorkItem(block: callback)
DispatchQueue.main.asyncAfter(deadline: .now()+t, execute: forceQuitTimerBlock!)
} else {
forceQuitTimerBlock = nil
}
}
internal mutating func setupWillLayout(duration: TimeInterval?, callback: @escaping () -> Void) {
willLayoutBlock?.cancel()
if let t = duration, t > 0 {
willLayoutBlock = DispatchWorkItem(block: callback)
DispatchQueue.main.asyncAfter(deadline: .now()+t, execute: willLayoutBlock!)
} else {
willLayoutBlock = nil
}
}
} }

View File

@ -58,10 +58,10 @@ public extension ProHUD {
view.tintColor = cfg.guard.tintColor view.tintColor = cfg.guard.tintColor
if let _ = title { if let _ = title {
loadTitle(title) add(title: title)
} }
if let _ = message { if let _ = message {
loadBody(message) add(message: message)
} }
cfg.guard.loadSubviews(self) cfg.guard.loadSubviews(self)
cfg.guard.reloadData(self) cfg.guard.reloadData(self)
@ -74,16 +74,6 @@ public extension ProHUD {
} }
public override func viewDidDisappear(_ animated: Bool) {
super.viewDidDisappear(animated)
}
deinit {
debug(self, "deinit")
}
} }
} }
@ -134,13 +124,13 @@ public extension ProHUD.Guard {
/// ///
/// - Parameter text: /// - Parameter text:
@discardableResult func loadTitle(_ text: String?) -> UILabel { @discardableResult func add(title: String?) -> UILabel {
let lb = UILabel() let lb = UILabel()
lb.font = cfg.guard.titleFont lb.font = cfg.guard.titleFont
lb.textColor = cfg.primaryLabelColor lb.textColor = cfg.primaryLabelColor
lb.numberOfLines = 0 lb.numberOfLines = 0
lb.textAlignment = .justified lb.textAlignment = .justified
lb.text = text lb.text = title
textStack.addArrangedSubview(lb) textStack.addArrangedSubview(lb)
if #available(iOS 11.0, *) { if #available(iOS 11.0, *) {
let count = textStack.arrangedSubviews.count let count = textStack.arrangedSubviews.count
@ -155,13 +145,13 @@ public extension ProHUD.Guard {
/// ///
/// - Parameter text: /// - Parameter text:
@discardableResult func loadBody(_ text: String?) -> UILabel { @discardableResult func add(message: String?) -> UILabel {
let lb = UILabel() let lb = UILabel()
lb.font = cfg.guard.bodyFont lb.font = cfg.guard.bodyFont
lb.textColor = cfg.secondaryLabelColor lb.textColor = cfg.secondaryLabelColor
lb.numberOfLines = 0 lb.numberOfLines = 0
lb.textAlignment = .justified lb.textAlignment = .justified
lb.text = text lb.text = message
textStack.addArrangedSubview(lb) textStack.addArrangedSubview(lb)
return lb return lb
} }
@ -170,7 +160,7 @@ public extension ProHUD.Guard {
/// - Parameter style: /// - Parameter style:
/// - Parameter title: /// - Parameter title:
/// - Parameter action: /// - Parameter action:
@discardableResult func loadButton(style: UIAlertAction.Style, title: String?, action: (() -> Void)? = nil) -> UIButton { @discardableResult func add(action style: UIAlertAction.Style, title: String?, action: (() -> Void)? = nil) -> UIButton {
let btn = Button.actionButton(title: title) let btn = Button.actionButton(title: title)
btn.titleLabel?.font = cfg.guard.buttonFont btn.titleLabel?.font = cfg.guard.buttonFont
if actionStack.superview == nil { if actionStack.superview == nil {
@ -188,6 +178,13 @@ public extension ProHUD.Guard {
} }
///
/// - Parameter callback:
@discardableResult func didDisappear(_ callback: (() -> Void)?) -> ProHUD.Guard {
disappearCallback = callback
return self
}
} }
fileprivate extension ProHUD.Guard { fileprivate extension ProHUD.Guard {

View File

@ -9,13 +9,14 @@
import UIKit import UIKit
public class HUDController: UIViewController { public class HUDController: UIViewController {
public var identifier = String(Date().timeIntervalSince1970)
internal var willLayout: DispatchWorkItem? /// ID
public var identifier = String(Date().timeIntervalSince1970)
/// ///
internal var disappearCallback: (() -> Void)? internal var disappearCallback: (() -> Void)?
///
internal var buttonEvents = [UIButton:() -> Void]() internal var buttonEvents = [UIButton:() -> Void]()
init() { init() {
@ -38,6 +39,10 @@ public class HUDController: UIViewController {
// Do any additional setup after loading the view. // Do any additional setup after loading the view.
} }
public override func viewDidDisappear(_ animated: Bool) {
super.viewDidDisappear(animated)
disappearCallback?()
}
} }

View File

@ -91,10 +91,6 @@ public extension ProHUD {
} }
public override func viewDidDisappear(_ animated: Bool) {
super.viewDidDisappear(animated)
disappearCallback?()
}
} }
@ -129,16 +125,8 @@ public extension ProHUD.Toast {
/// ///
/// - Parameter duration: /// - Parameter duration:
@discardableResult func duration(_ duration: TimeInterval?) -> ProHUD.Toast { @discardableResult func duration(_ duration: TimeInterval?) -> ProHUD.Toast {
model.duration = duration model.setupDuration(duration: duration) { [weak self] in
// self?.pop()
model.durationBlock?.cancel()
if let t = duration, t > 0 {
model.durationBlock = DispatchWorkItem(block: { [weak self] in
self?.pop()
})
DispatchQueue.main.asyncAfter(deadline: .now()+t, execute: model.durationBlock!)
} else {
model.durationBlock = nil
} }
return self return self
} }
@ -161,12 +149,10 @@ public extension ProHUD.Toast {
/// - Parameter scene: /// - Parameter scene:
/// - Parameter title: /// - Parameter title:
/// - Parameter message: /// - Parameter message:
/// - Parameter icon: @discardableResult func update(scene: Scene, title: String?, message: String?) -> ProHUD.Toast {
@discardableResult func update(scene: Scene, title: String? = nil, message: String? = nil, icon: UIImage? = nil) -> ProHUD.Toast {
model.scene = scene model.scene = scene
model.title = title model.title = title
model.message = message model.message = message
model.icon = icon
cfg.toast.reloadData(self) cfg.toast.reloadData(self)
return self return self
} }
@ -175,7 +161,7 @@ public extension ProHUD.Toast {
/// - Parameter title: /// - Parameter title:
@discardableResult func update(title: String?) -> ProHUD.Toast { @discardableResult func update(title: String?) -> ProHUD.Toast {
model.title = title model.title = title
titleLabel.text = title cfg.toast.reloadData(self)
return self return self
} }
@ -183,7 +169,7 @@ public extension ProHUD.Toast {
/// - Parameter message: /// - Parameter message:
@discardableResult func update(message: String?) -> ProHUD.Toast { @discardableResult func update(message: String?) -> ProHUD.Toast {
model.message = message model.message = message
bodyLabel.text = message cfg.toast.reloadData(self)
return self return self
} }
@ -191,7 +177,7 @@ public extension ProHUD.Toast {
/// - Parameter icon: /// - Parameter icon:
@discardableResult func update(icon: UIImage?) -> ProHUD.Toast { @discardableResult func update(icon: UIImage?) -> ProHUD.Toast {
model.icon = icon model.icon = icon
imageView.image = icon cfg.toast.reloadData(self)
return self return self
} }
@ -292,8 +278,8 @@ public extension ProHUD {
/// - Parameter title: /// - Parameter title:
/// - Parameter message: /// - Parameter message:
/// - Parameter icon: /// - Parameter icon:
@discardableResult func push(toast scene: Toast.Scene, title: String? = nil, message: String? = nil, icon: UIImage? = nil) -> Toast { @discardableResult func push(toast scene: Toast.Scene, title: String? = nil, message: String? = nil) -> Toast {
return push(Toast(scene: scene, title: title, message: message, icon: icon)) return push(Toast(scene: scene, title: title, message: message))
} }
/// toast /// toast
@ -346,8 +332,8 @@ public extension ProHUD {
/// - Parameter title: /// - Parameter title:
/// - Parameter message: /// - Parameter message:
/// - Parameter icon: /// - Parameter icon:
@discardableResult class func push(toast: Toast.Scene, title: String? = nil, message: String? = nil, icon: UIImage? = nil) -> Toast { @discardableResult class func push(toast: Toast.Scene, title: String? = nil, message: String? = nil) -> Toast {
return shared.push(toast: toast, title: title, message: message, icon: icon) return shared.push(toast: toast, title: title, message: message)
} }
/// toast /// toast

View File

@ -57,10 +57,15 @@ public extension ProHUD.Toast {
/// ///
internal var tapCallback: (() -> Void)? internal var tapCallback: (() -> Void)?
public init(title: String? = nil, message: String? = nil, icon: UIImage? = nil) { internal mutating func setupDuration(duration: TimeInterval?, callback: @escaping () -> Void) {
self.title = title self.duration = duration
self.message = message durationBlock?.cancel()
self.icon = icon if let t = duration, t > 0 {
durationBlock = DispatchWorkItem(block: callback)
DispatchQueue.main.asyncAfter(deadline: .now()+t, execute: durationBlock!)
} else {
durationBlock = nil
}
} }