mirror of https://github.com/xaoxuu/ProHUD
tmp
This commit is contained in:
parent
6596e6c971
commit
26d7aa0049
|
@ -18,8 +18,15 @@ class ViewController: UIViewController {
|
|||
|
||||
ProHUD.config { (cfg) in
|
||||
cfg.alert { (a) in
|
||||
a.forceQuitTimer = 2
|
||||
a.duration = 1
|
||||
a.forceQuitTimer = 3
|
||||
// a.iconSize = .init(width: 20, height: 80)
|
||||
// a.reloadData
|
||||
// a.iconSize = .init(width: 20, height: 80)
|
||||
a.iconForScene { (s) -> UIImage? in
|
||||
return UIImage(named: "icon_download")
|
||||
}
|
||||
|
||||
}
|
||||
cfg.toast { (t) in
|
||||
// t.iconSize = .init(width: 300, height: 30)
|
||||
|
@ -30,43 +37,134 @@ class ViewController: UIViewController {
|
|||
|
||||
|
||||
@IBAction func test(_ sender: UIButton) {
|
||||
|
||||
|
||||
// testAlert()
|
||||
testToast()
|
||||
// testUpdateAction()
|
||||
testGuard()
|
||||
// testGuard()
|
||||
// fastGuard()
|
||||
}
|
||||
|
||||
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")
|
||||
func testAlert() {
|
||||
let a = Alert.push(scene: .loading) { (a) in
|
||||
|
||||
// a.update()
|
||||
}
|
||||
}).add(action: .cancel, title: "取消", action: nil)
|
||||
a.update { (vm) in
|
||||
vm.add(action: .default, title: "OK", handler: nil)
|
||||
}
|
||||
// a.update()
|
||||
// Alert.push(scene: .loading, title: "Loading") { (a) in
|
||||
// a.animate(rotate: true)
|
||||
// DispatchQueue.main.asyncAfter(deadline: .now()+1) {
|
||||
// a.update { (vm) in
|
||||
// vm.message = "请稍后片刻"
|
||||
// }
|
||||
// a.animate(rotate: true)
|
||||
// }
|
||||
// DispatchQueue.main.asyncAfter(deadline: .now()+2) {
|
||||
// a.update { (vm) in
|
||||
// vm.message = "请稍后片刻请稍后片刻"
|
||||
// }
|
||||
// a.animate(rotate: true)
|
||||
// }
|
||||
// DispatchQueue.main.asyncAfter(deadline: .now()+3) {
|
||||
// a.update { (vm) in
|
||||
// vm.scene = .success
|
||||
// vm.add(action: .default, title: "OK") { [weak a] in
|
||||
// a?.pop()
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// DispatchQueue.main.asyncAfter(deadline: .now()+4) {
|
||||
// a.update { (vm) in
|
||||
// vm.update(action: 0, style: .cancel, title: "Cancel", handler: nil)
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// Alert.push(scene: .delete, title: "确认删除", message: "此操作不可撤销!此操作不可撤销!此操作不可撤销!") { (a) in
|
||||
// a.identifier = ""
|
||||
// DispatchQueue.main.asyncAfter(deadline: .now()+1) {
|
||||
// a.update { (vm) in
|
||||
// vm.add(action: .destructive, title: "确认") { [weak a] in
|
||||
// a?.update({ (vm) in
|
||||
// vm.message = "但是饭撒 打算放过"
|
||||
// vm.remove(action: 1)
|
||||
// vm.update(action: 0, style: .destructive, title: "确认", handler: {
|
||||
// a?.pop()
|
||||
// })
|
||||
// })
|
||||
// }
|
||||
// vm.add(action: .cancel, title: "取消", handler: nil)
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// }
|
||||
}
|
||||
|
||||
func testDelete() {
|
||||
let a = Alert.push(scene: .delete, title: "确认删除", message: "此操作不可撤销")
|
||||
a.update { (vm) in
|
||||
vm.add(action: .destructive, title: "确认", handler: { [weak a] in
|
||||
a?.update { (vm) in
|
||||
vm.scene = .loading
|
||||
vm.title = "正在删除"
|
||||
vm.message = "请稍后片刻"
|
||||
vm.remove(action: 0, 1)
|
||||
}
|
||||
DispatchQueue.main.asyncAfter(deadline: .now()+1) {
|
||||
a?.update { (vm) in
|
||||
vm.scene = .success
|
||||
vm.title = "删除成功"
|
||||
vm.message = "啊哈哈哈哈"
|
||||
vm.duration = 2
|
||||
}
|
||||
Toast.push(scene: .success, title: "删除成功", message: "aaa")
|
||||
}
|
||||
})
|
||||
vm.add(action: .cancel, title: "取消", handler: nil)
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
func testToast() {
|
||||
let t = ProHUD.Toast(scene: .loading, title: "正在加载", message: "请稍候片刻")
|
||||
let t = Toast(scene: .loading, title: "正在加载", message: "请稍候片刻")
|
||||
|
||||
let a = ProHUD.push(alert : .loading, title: "正在加载", message: "请稍候片刻")
|
||||
let a = Alert.push(scene : .loading, title: "正在加载", message: "请稍候片刻")
|
||||
a.didForceQuit {
|
||||
hud.push(t)
|
||||
t.push()
|
||||
}
|
||||
|
||||
t.didTapped { [weak t] in
|
||||
t?.pop()
|
||||
let a2 = ProHUD.push(alert: .loading, title: "正在加载", message: "马上就要成功了")
|
||||
Alert.push(scene: .loading, title: "正在加载", message: "马上就要成功了")
|
||||
DispatchQueue.main.asyncAfter(deadline: .now()+1) {
|
||||
let a3 = ProHUD.push(alert: .error, title: "加载失败", message: "点击充实")
|
||||
a3.add(action: .default, title: "重新加载") { [weak a3] in
|
||||
a3?.update(scene: .success, title: "加载成功", message: "马上就要成功了")
|
||||
a3?.update(action: 0, style: .default, title: "OK", action: { [weak a3] in
|
||||
a3?.pop()
|
||||
}).remove(action: 1, 2)
|
||||
}.add(action: .destructive, title: "终止", action: nil).add(action: .cancel, title: "取消", action: nil)
|
||||
Alert.push(scene: .error, title: "加载失败", message: "点击充实") { (vm) in
|
||||
vm.duration = 0
|
||||
vm.identifier = "hehe"
|
||||
let a = vm.vc!
|
||||
vm.add(action: .default, title: "重新加载") {
|
||||
a.vm.scene = .success
|
||||
a.vm.title = "加载成功"
|
||||
a.vm.message = "马上就要成功了aaaa"
|
||||
a.vm.remove(action: 1, 2)
|
||||
a.vm.update(action: 0, style: .default, title: "OK") { [weak a] in
|
||||
a?.pop()
|
||||
}
|
||||
|
||||
}
|
||||
vm.add(action: .destructive, title: "终止", handler: nil)
|
||||
vm.add(action: .cancel, title: "取消", handler: nil)
|
||||
}
|
||||
|
||||
DispatchQueue.main.asyncAfter(deadline: .now()+1) {
|
||||
if let a = Alert.alerts("hehe").last {
|
||||
a.update { (vm) in
|
||||
vm.add(action: .cancel, title: "CANCEL", handler: nil)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
@ -80,37 +178,47 @@ class ViewController: UIViewController {
|
|||
|
||||
g.add(title: "呵呵")
|
||||
g.add(message: "请打开相机权限开关,否则无法进行测量。请打开相机权限开关,否则无法进行测量。")
|
||||
g.add(action: .default, title: "测试弹窗", action: { [weak self] in
|
||||
g.add(action: .default, title: "测试弹窗", handler: { [weak self] in
|
||||
self?.testToast()
|
||||
})
|
||||
g.add(action: .destructive, title: "测试删除弹窗", action: { [weak self] in
|
||||
g.add(action: .destructive, title: "测试删除弹窗", handler: { [weak self] in
|
||||
self?.testDelete()
|
||||
})
|
||||
g.add(action: .cancel, title: "我知道了", action: nil)
|
||||
g.add(action: .cancel, title: "我知道了", handler: nil)
|
||||
|
||||
g.push(to: self)
|
||||
debugPrint("test: ", g)
|
||||
}
|
||||
|
||||
func testUpdateAction() {
|
||||
let a = ProHUD.push(alert: .confirm, title: "确认删除", message: "此操作无法撤销")
|
||||
a.add(action: .destructive, title: "删除") {
|
||||
a.remove(action: 0, 1).update(scene: .loading, title: "正在删除", message: "请稍后片刻")
|
||||
}.add(action: .cancel, title: "取消", action: nil)
|
||||
let a = Alert.push(scene: .confirm, title: "确认删除", message: "此操作无法撤销")
|
||||
a.update { (vm) in
|
||||
vm.add(action: .destructive, title: "删除") {
|
||||
a.update { (vm) in
|
||||
vm.remove(action: 0, 1)
|
||||
vm.scene = .loading
|
||||
vm.title = "正在删除"
|
||||
vm.message = "请稍后片刻"
|
||||
}
|
||||
}
|
||||
vm.add(action: .cancel, title: "取消", handler: nil)
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
func fastGuard() {
|
||||
let g = ProHUD.push(guard: self, title: "测试", message: "测试测试")
|
||||
g.add(action: .default, title: "默认按钮", action: {
|
||||
Guard.push(to: self) { (vm) in
|
||||
vm.add(title: "测试")
|
||||
vm.add(message: "测试测试")
|
||||
vm.add(action: .default, title: "默认按钮", handler: {
|
||||
|
||||
})
|
||||
g.add(action: .cancel, title: "取消", action: nil)
|
||||
g.view.backgroundColor = .clear
|
||||
vm.add(action: .cancel, title: "取消", handler: nil)
|
||||
vm.vc?.view.backgroundColor = .clear
|
||||
}
|
||||
|
||||
// g.contentView.backgroundColor = UIColor.white
|
||||
|
||||
|
||||
}
|
||||
|
@ -120,37 +228,6 @@ class ViewController: UIViewController {
|
|||
|
||||
|
||||
|
||||
|
||||
//
|
||||
// ProHUD.show(alert: .loading, title: "确认删除", message: "此操作不可撤销").timeout(nil)
|
||||
//
|
||||
// ProHUD.show(alert: .confirm, title: "确认删除", message: "此操作不可撤销").timeout(3)
|
||||
|
||||
//
|
||||
// a.addAction(style: .destructive, title: "删除") { [weak a] in
|
||||
// a?.updateContent(scene: .success, title: "操作成功", message: "恭喜,您已经成功删除了xxx")
|
||||
// a?.updateAction(index: 0, style: .default, title: "好的", action: {
|
||||
// a?.remove()
|
||||
// }).removeAction(index: 1)
|
||||
//// a?.updateContent(scene: .success, title: "操作成功").removeAction(index: -1).timeout(2)
|
||||
// }.addAction(style: .cancel, title: "取消", action: nil).didDisappear {
|
||||
// debugPrint("didDisappear")
|
||||
// }
|
||||
//
|
||||
// ProHUD.show(alert: .delete, title: "克里斯蒂娜删除", message: "克里斯蒂娜疯狂拉升的反馈老实交代分开就撒开了击快乐圣诞").addAction(style: .destructive, title: "删除") {
|
||||
//
|
||||
// }.addAction(style: .cancel, title: "取消", action: nil).didDisappear {
|
||||
// debugPrint("didDisappear")
|
||||
// }.addAction(style: .cancel, title: nil) {
|
||||
//
|
||||
// }
|
||||
|
||||
|
||||
|
||||
|
||||
// ProHUD.show(toast: .loading, title: "正在加载", message: "拉升的反馈老实交代分开就撒开了击快乐圣反馈老实交代分开就撒开了击快乐圣")
|
||||
// ProHUD.show(toast: .loading, title: "正在加载", message: "哈克里斯蒂娜疯狂拉升的反馈老实交代分开就撒开了击快乐圣诞哈克里斯蒂娜疯狂拉升的反馈老实交代分开就撒开了击快乐圣诞")
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
CD95D26B22E72DB3007559A3 /* ProHUD.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD95D26A22E72DB3007559A3 /* ProHUD.swift */; };
|
||||
CDB6A07B22EEF06500AF6CF0 /* HUDController.swift in Sources */ = {isa = PBXBuildFile; fileRef = CDB6A07A22EEF06500AF6CF0 /* HUDController.swift */; };
|
||||
CDB6A07D22EEF19D00AF6CF0 /* HUDConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = CDB6A07C22EEF19D00AF6CF0 /* HUDConfig.swift */; };
|
||||
CDC39CFD22FD6DDF0070E914 /* GuardModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = CDC39CFC22FD6DDF0070E914 /* GuardModel.swift */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
|
@ -50,6 +51,7 @@
|
|||
CD95D26A22E72DB3007559A3 /* ProHUD.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProHUD.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>"; };
|
||||
CDC39CFC22FD6DDF0070E914 /* GuardModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GuardModel.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>"; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
|
@ -110,6 +112,7 @@
|
|||
CD6CD87422F185C200F4FD4A /* GuardController.swift */,
|
||||
CD6CD87822F185D000F4FD4A /* GuardConfig.swift */,
|
||||
CD6CD87A22F185D600F4FD4A /* GuardView.swift */,
|
||||
CDC39CFC22FD6DDF0070E914 /* GuardModel.swift */,
|
||||
);
|
||||
path = Guard;
|
||||
sourceTree = "<group>";
|
||||
|
@ -292,6 +295,7 @@
|
|||
CD16490B22EF09AB0077988C /* AlertModel.swift in Sources */,
|
||||
CD16491222EF0D900077988C /* HUDView.swift in Sources */,
|
||||
CDB6A07B22EEF06500AF6CF0 /* HUDController.swift in Sources */,
|
||||
CDC39CFD22FD6DDF0070E914 /* GuardModel.swift in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
|
|
|
@ -11,7 +11,7 @@ import SnapKit
|
|||
import Inspire
|
||||
|
||||
public extension ProHUD.Configuration {
|
||||
struct Alert {
|
||||
class Alert {
|
||||
// MARK: 卡片样式
|
||||
/// 最大宽度(用于优化横屏或者iPad显示)
|
||||
public var maxWidth = CGFloat(400)
|
||||
|
@ -28,6 +28,10 @@ public extension ProHUD.Configuration {
|
|||
/// 图标尺寸
|
||||
public var iconSize = CGSize(width: 48, height: 48)
|
||||
|
||||
public func iconForScene(_ callback: @escaping (ProHUD.Alert.Scene) -> UIImage?) {
|
||||
privIconForScene = callback
|
||||
}
|
||||
|
||||
// MARK: 文本样式
|
||||
/// 标题字体
|
||||
public var titleFont = UIFont.boldSystemFont(ofSize: 22)
|
||||
|
@ -48,18 +52,14 @@ public extension ProHUD.Configuration {
|
|||
|
||||
// MARK: 生命周期
|
||||
|
||||
/// 加载视图
|
||||
/// - Parameter callback: 回调代码
|
||||
public mutating func loadSubviews(_ callback: @escaping (ProHUD.Alert) -> Void) {
|
||||
privLoadSubviews = callback
|
||||
}
|
||||
|
||||
/// 更新视图
|
||||
/// - Parameter callback: 回调代码
|
||||
public mutating func reloadData(_ callback: @escaping (ProHUD.Alert) -> Void) {
|
||||
/// 刷新数据和布局
|
||||
public func reloadData(_ callback: @escaping (ProHUD.Alert) -> Void) {
|
||||
privReloadData = callback
|
||||
}
|
||||
|
||||
/// 非Loading弹窗的默认持续时间
|
||||
public var duration = TimeInterval(2)
|
||||
|
||||
/// 多少秒后显示强制退出的按钮(只有无按钮的弹窗才会出现)
|
||||
public var forceQuitTimer = TimeInterval(30)
|
||||
|
||||
|
@ -68,77 +68,41 @@ public extension ProHUD.Configuration {
|
|||
|
||||
/// 加载强制退出按钮
|
||||
/// - Parameter callback: 回调代码
|
||||
public mutating func loadForceQuitButton(_ callback: @escaping (ProHUD.Alert) -> Void) {
|
||||
public func loadForceQuitButton(_ callback: @escaping (ProHUD.Alert) -> Void) {
|
||||
privLoadForceQuitButton = callback
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// MARK: - 内部调用
|
||||
|
||||
internal extension ProHUD.Configuration.Alert {
|
||||
var reloadData: (ProHUD.Alert) -> Void {
|
||||
return privReloadData
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// MARK: - 默认实现
|
||||
|
||||
internal extension ProHUD.Configuration.Alert {
|
||||
var loadSubviews: (ProHUD.Alert) -> Void {
|
||||
return privLoadSubviews
|
||||
}
|
||||
|
||||
var reloadData: (ProHUD.Alert) -> Void {
|
||||
return privReloadData
|
||||
}
|
||||
|
||||
var loadForceQuitButton: (ProHUD.Alert) -> Void {
|
||||
return privLoadForceQuitButton
|
||||
}
|
||||
|
||||
var setupDefaultDuration: (ProHUD.Alert) -> Void {
|
||||
fileprivate var privLayoutContentView: (ProHUD.Alert) -> Void = {
|
||||
return { (vc) in
|
||||
// 如果设置了超时时间,但是增加了按钮
|
||||
if let t = vc.model.duration, t > 0 {
|
||||
if vc.buttonEvents.count > 0 {
|
||||
vc.duration(nil)
|
||||
}
|
||||
} else if vc.model.duration == nil && vc.model.scene != .loading {
|
||||
// 如果没有设置超时时间
|
||||
vc.duration(2)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var reloadStack: (ProHUD.Alert) -> Void {
|
||||
return { (vc) in
|
||||
if vc.textStack.arrangedSubviews.count > 0 {
|
||||
vc.contentStack.addArrangedSubview(vc.textStack)
|
||||
} else {
|
||||
vc.textStack.removeFromSuperview()
|
||||
}
|
||||
if vc.actionStack.arrangedSubviews.count > 0 {
|
||||
vc.contentStack.addArrangedSubview(vc.actionStack)
|
||||
} else {
|
||||
vc.actionStack.removeFromSuperview()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fileprivate var privLoadSubviews: (ProHUD.Alert) -> Void = {
|
||||
return { (vc) in
|
||||
debug(vc, "loadSubviews")
|
||||
let config = cfg.alert
|
||||
if vc.contentView.superview == nil {
|
||||
vc.view.addSubview(vc.contentView)
|
||||
vc.contentView.contentView.addSubview(vc.contentStack)
|
||||
|
||||
vc.contentStack.spacing = cfg.alert.margin + cfg.alert.padding
|
||||
|
||||
vc.contentView.layer.masksToBounds = true
|
||||
vc.contentView.layer.cornerRadius = cfg.alert.cornerRadius
|
||||
|
||||
let maxWidth = CGFloat.maximum(CGFloat.minimum(UIScreen.main.bounds.width * 0.68, cfg.alert.maxWidth), 268)
|
||||
vc.contentView.snp.makeConstraints { (mk) in
|
||||
mk.center.equalToSuperview()
|
||||
mk.width.lessThanOrEqualTo(maxWidth)
|
||||
}
|
||||
}
|
||||
if vc.contentStack.superview == nil {
|
||||
vc.contentView.contentView.addSubview(vc.contentStack)
|
||||
vc.contentStack.spacing = cfg.alert.margin + cfg.alert.padding
|
||||
vc.contentStack.snp.makeConstraints { (mk) in
|
||||
mk.centerX.equalToSuperview()
|
||||
mk.top.equalToSuperview().offset(cfg.alert.padding)
|
||||
|
@ -147,23 +111,13 @@ fileprivate var privLoadSubviews: (ProHUD.Alert) -> Void = {
|
|||
mk.trailing.equalToSuperview().offset(-cfg.alert.padding)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}()
|
||||
|
||||
fileprivate var privReloadData: (ProHUD.Alert) -> Void = {
|
||||
return { (vc) in
|
||||
debug(vc, "reloadData")
|
||||
let config = cfg.alert
|
||||
let isFirstLayout: Bool
|
||||
// 图标和文字至少有一个,如果都没有添加到视图中,说明是第一次layout
|
||||
if vc.textStack.superview == nil && vc.imageView?.superview == nil {
|
||||
isFirstLayout = true
|
||||
} else {
|
||||
isFirstLayout = false
|
||||
}
|
||||
fileprivate var privIconForScene: (ProHUD.Alert.Scene) -> UIImage? = {
|
||||
return { (scene) in
|
||||
let imgStr: String
|
||||
switch vc.model.scene {
|
||||
switch scene {
|
||||
case .success:
|
||||
imgStr = "ProHUDSuccess"
|
||||
case .warning:
|
||||
|
@ -179,7 +133,14 @@ fileprivate var privReloadData: (ProHUD.Alert) -> Void = {
|
|||
default:
|
||||
imgStr = "ProHUDMessage"
|
||||
}
|
||||
let img = vc.model.icon ?? ProHUD.image(named: imgStr)
|
||||
return ProHUD.image(named: imgStr)
|
||||
}
|
||||
}()
|
||||
|
||||
fileprivate var privUpdateImage: (ProHUD.Alert) -> Void = {
|
||||
return { (vc) in
|
||||
let config = cfg.alert
|
||||
let img = vc.vm.icon ?? privIconForScene(vc.vm.scene)
|
||||
if let imgv = vc.imageView {
|
||||
imgv.image = img
|
||||
} else {
|
||||
|
@ -197,9 +158,13 @@ fileprivate var privReloadData: (ProHUD.Alert) -> Void = {
|
|||
vc.imageView = icon
|
||||
}
|
||||
vc.imageView?.layer.removeAllAnimations()
|
||||
}
|
||||
}()
|
||||
|
||||
// text
|
||||
if vc.model.title?.count ?? 0 > 0 || vc.model.message?.count ?? 0 > 0 {
|
||||
fileprivate var privUpdateTextStack: (ProHUD.Alert) -> Void = {
|
||||
return { (vc) in
|
||||
let config = cfg.alert
|
||||
if vc.vm.title?.count ?? 0 > 0 || vc.vm.message?.count ?? 0 > 0 {
|
||||
vc.contentStack.addArrangedSubview(vc.textStack)
|
||||
vc.textStack.snp.makeConstraints { (mk) in
|
||||
mk.top.greaterThanOrEqualTo(vc.contentView).offset(config.padding*1.75)
|
||||
|
@ -212,19 +177,19 @@ fileprivate var privReloadData: (ProHUD.Alert) -> Void = {
|
|||
mk.trailing.lessThanOrEqualTo(vc.contentView).offset(-config.padding*2)
|
||||
}
|
||||
}
|
||||
if vc.model.title?.count ?? 0 > 0 {
|
||||
if vc.vm.title?.count ?? 0 > 0 {
|
||||
if let lb = vc.titleLabel {
|
||||
lb.text = vc.model.title
|
||||
lb.text = vc.vm.title
|
||||
} else {
|
||||
let title = UILabel()
|
||||
title.textAlignment = .center
|
||||
title.numberOfLines = config.titleMaxLines
|
||||
title.textColor = cfg.primaryLabelColor
|
||||
title.text = vc.model.title
|
||||
title.text = vc.vm.title
|
||||
vc.textStack.addArrangedSubview(title)
|
||||
vc.titleLabel = title
|
||||
}
|
||||
if vc.model.message?.count ?? 0 > 0 {
|
||||
if vc.vm.message?.count ?? 0 > 0 {
|
||||
// 有message
|
||||
vc.titleLabel?.font = config.titleFont
|
||||
} else {
|
||||
|
@ -234,20 +199,20 @@ fileprivate var privReloadData: (ProHUD.Alert) -> Void = {
|
|||
} else {
|
||||
vc.titleLabel?.removeFromSuperview()
|
||||
}
|
||||
if vc.model.message?.count ?? 0 > 0 {
|
||||
if vc.vm.message?.count ?? 0 > 0 {
|
||||
if let lb = vc.bodyLabel {
|
||||
lb.text = vc.model.message
|
||||
lb.text = vc.vm.message
|
||||
} else {
|
||||
let body = UILabel()
|
||||
body.textAlignment = .center
|
||||
body.font = config.bodyFont
|
||||
body.numberOfLines = config.bodyMaxLines
|
||||
body.textColor = cfg.secondaryLabelColor
|
||||
body.text = vc.model.message
|
||||
body.text = vc.vm.message
|
||||
vc.textStack.addArrangedSubview(body)
|
||||
vc.bodyLabel = body
|
||||
}
|
||||
if vc.model.title?.count ?? 0 > 0 {
|
||||
if vc.vm.title?.count ?? 0 > 0 {
|
||||
// 有title
|
||||
vc.bodyLabel?.font = config.bodyFont
|
||||
} else {
|
||||
|
@ -260,18 +225,19 @@ fileprivate var privReloadData: (ProHUD.Alert) -> Void = {
|
|||
} else {
|
||||
vc.textStack.removeFromSuperview()
|
||||
}
|
||||
if vc.actionStack.superview != nil {
|
||||
if isFirstLayout {
|
||||
vc.contentStack.addArrangedSubview(vc.actionStack)
|
||||
} else {
|
||||
vc.actionStack.transform = .init(scaleX: 1, y: 0.001)
|
||||
UIView.animateForAlert {
|
||||
vc.contentStack.addArrangedSubview(vc.actionStack)
|
||||
vc.view.layoutIfNeeded()
|
||||
}
|
||||
vc.textStack.layoutIfNeeded()
|
||||
}
|
||||
}()
|
||||
|
||||
|
||||
fileprivate var privUpdateActionStack: (ProHUD.Alert) -> Void = {
|
||||
return { (vc) in
|
||||
let config = cfg.alert
|
||||
if vc.buttonEvents.count > 0 {
|
||||
// 有按钮
|
||||
vc.contentStack.addArrangedSubview(vc.actionStack)
|
||||
// 适配横竖屏和iPad
|
||||
if isPortrait == false {
|
||||
if isPortrait == false && vc.buttonEvents.count < 4 {
|
||||
vc.actionStack.axis = .horizontal
|
||||
vc.actionStack.alignment = .fill
|
||||
vc.actionStack.distribution = .fillEqually
|
||||
|
@ -280,28 +246,14 @@ fileprivate var privReloadData: (ProHUD.Alert) -> Void = {
|
|||
mk.width.greaterThanOrEqualTo(200)
|
||||
mk.leading.trailing.equalToSuperview()
|
||||
}
|
||||
if isFirstLayout == false {
|
||||
UIView.animateForAlert {
|
||||
vc.actionStack.transform = .identity
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if isFirstLayout {
|
||||
vc.view.layoutIfNeeded()
|
||||
vc.imageView?.transform = .init(scaleX: 0.75, y: 0.75)
|
||||
UIView.animateForAlert {
|
||||
vc.imageView?.transform = .identity
|
||||
vc.view.layoutIfNeeded()
|
||||
}
|
||||
} else {
|
||||
UIView.animateForAlert {
|
||||
vc.view.layoutIfNeeded()
|
||||
// 无按钮
|
||||
for v in vc.actionStack.arrangedSubviews {
|
||||
v.removeFromSuperview()
|
||||
}
|
||||
vc.actionStack.removeFromSuperview()
|
||||
}
|
||||
|
||||
|
||||
vc.actionStack.layoutIfNeeded()
|
||||
}
|
||||
}()
|
||||
|
||||
|
@ -335,12 +287,74 @@ fileprivate var privLoadForceQuitButton: (ProHUD.Alert) -> Void = {
|
|||
bg.transform = .identity
|
||||
}
|
||||
vc.addTouchUpAction(for: btn) { [weak vc] in
|
||||
debug("点击了隐藏")
|
||||
vc?.model.forceQuitCallback?()
|
||||
debug("点击了【\(config.forceQuitTitle)】")
|
||||
vc?.vm.forceQuitCallback?()
|
||||
vc?.pop()
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
/// 刷新数据和布局
|
||||
fileprivate var privReloadData: (ProHUD.Alert) -> Void = {
|
||||
return { (vc) in
|
||||
debug(vc, "reloadData")
|
||||
let config = cfg.alert
|
||||
let isFirstLayout: Bool
|
||||
if vc.contentView.superview == nil {
|
||||
isFirstLayout = true
|
||||
// 布局主容器视图
|
||||
privLayoutContentView(vc)
|
||||
} else {
|
||||
isFirstLayout = false
|
||||
}
|
||||
// 更新图片
|
||||
privUpdateImage(vc)
|
||||
|
||||
// 更新文本容器
|
||||
privUpdateTextStack(vc)
|
||||
|
||||
// 更新操作容器
|
||||
privUpdateActionStack(vc)
|
||||
vc.contentStack.layoutIfNeeded()
|
||||
vc.contentView.layoutIfNeeded()
|
||||
|
||||
// 动画
|
||||
if isFirstLayout {
|
||||
vc.view.layoutIfNeeded()
|
||||
vc.imageView?.transform = .init(scaleX: 0.75, y: 0.75)
|
||||
UIView.animateForAlert {
|
||||
vc.view.layoutIfNeeded()
|
||||
vc.imageView?.transform = .identity
|
||||
}
|
||||
} else {
|
||||
UIView.animateForAlert {
|
||||
vc.view.layoutIfNeeded()
|
||||
}
|
||||
}
|
||||
|
||||
// 设置默认持续时间
|
||||
if vc.vm.duration == nil {
|
||||
if vc.vm.scene == .loading {
|
||||
vc.vm.duration = 0
|
||||
} else {
|
||||
vc.vm.duration = config.duration
|
||||
}
|
||||
}
|
||||
|
||||
// 强制退出按钮
|
||||
vc.vm.forceQuitTimerBlock?.cancel()
|
||||
if vc.buttonEvents.count == 0 {
|
||||
vc.vm.forceQuitTimerBlock = DispatchWorkItem(block: { [weak vc] in
|
||||
if let vc = vc {
|
||||
if vc.buttonEvents.count == 0 {
|
||||
privLoadForceQuitButton(vc)
|
||||
}
|
||||
}
|
||||
})
|
||||
DispatchQueue.main.asyncAfter(deadline: .now() + config.forceQuitTimer, execute: vc.vm.forceQuitTimerBlock!)
|
||||
} else {
|
||||
vc.vm.forceQuitTimerBlock = nil
|
||||
}
|
||||
|
||||
}
|
||||
}()
|
||||
|
|
|
@ -53,28 +53,32 @@ public extension ProHUD {
|
|||
}()
|
||||
|
||||
/// 视图模型
|
||||
public var model = ViewModel()
|
||||
|
||||
public var vm = ViewModel()
|
||||
|
||||
// MARK: 生命周期
|
||||
internal var isLoadFinished = false
|
||||
|
||||
/// 实例化
|
||||
/// - Parameter scene: 场景
|
||||
/// - Parameter title: 标题
|
||||
/// - Parameter message: 内容
|
||||
/// - Parameter icon: 图标
|
||||
public convenience init(scene: Scene = .default, title: String? = nil, message: String? = nil, icon: UIImage? = nil, actions: ((Alert) -> Void)? = nil) {
|
||||
public convenience init(scene: Scene = .default, title: String? = nil, message: String? = nil, icon: UIImage? = nil, actions: ((inout ViewModel) -> Void)? = nil) {
|
||||
self.init()
|
||||
view.tintColor = cfg.alert.tintColor
|
||||
model.scene = scene
|
||||
model.title = title
|
||||
model.message = message
|
||||
model.icon = icon
|
||||
actions?(self)
|
||||
willLayoutSubviews()
|
||||
|
||||
vm.vc = self
|
||||
vm.scene = scene
|
||||
vm.title = title
|
||||
vm.message = message
|
||||
vm.icon = icon
|
||||
actions?(&vm)
|
||||
}
|
||||
|
||||
public override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
view.tintColor = cfg.alert.tintColor
|
||||
cfg.alert.reloadData(self)
|
||||
isLoadFinished = true
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@ -88,7 +92,6 @@ public extension Alert {
|
|||
|
||||
/// 推入屏幕
|
||||
@discardableResult func push() -> Alert {
|
||||
let hud = ProHUD.shared
|
||||
if Alert.alerts.contains(self) == false {
|
||||
let window = Alert.getAlertWindow(self)
|
||||
window.makeKeyAndVisible()
|
||||
|
@ -104,11 +107,6 @@ public extension Alert {
|
|||
Alert.alerts.append(self)
|
||||
}
|
||||
Alert.updateAlertsLayout()
|
||||
|
||||
// setup duration
|
||||
if let _ = model.duration, model.durationBlock == nil {
|
||||
duration(model.duration)
|
||||
}
|
||||
return self
|
||||
}
|
||||
|
||||
|
@ -137,22 +135,11 @@ public extension Alert {
|
|||
|
||||
// MARK: 设置函数
|
||||
|
||||
/// 添加按钮
|
||||
/// - Parameter style: 样式
|
||||
/// - Parameter text: 标题
|
||||
/// - Parameter handler: 事件处理
|
||||
@discardableResult func add(action style: UIAlertAction.Style, title: String?, handler: (() -> Void)?) -> UIButton {
|
||||
let btn = privAddButton(custom: Button.actionButton(title: title), action: handler)
|
||||
if let b = btn as? Button {
|
||||
b.update(style: style)
|
||||
}
|
||||
return btn
|
||||
}
|
||||
|
||||
/// 最小化事件
|
||||
/// - Parameter callback: 事件回调
|
||||
@discardableResult func didForceQuit(_ callback: (() -> Void)?) -> Alert {
|
||||
model.forceQuitCallback = callback
|
||||
vm.forceQuitCallback = callback
|
||||
return self
|
||||
}
|
||||
|
||||
|
@ -163,77 +150,29 @@ public extension Alert {
|
|||
return self
|
||||
}
|
||||
|
||||
/// 设置持续时间
|
||||
/// - Parameter duration: 持续时间
|
||||
@discardableResult func duration(_ duration: TimeInterval?) -> Alert {
|
||||
model.setupDuration(duration: duration) { [weak self] in
|
||||
self?.pop()
|
||||
}
|
||||
return self
|
||||
}
|
||||
|
||||
/// 更新
|
||||
/// - Parameter scene: 场景
|
||||
/// - Parameter title: 标题
|
||||
/// - Parameter message: 正文
|
||||
@discardableResult func update(scene: Scene, title: String?, message: String?) -> Alert {
|
||||
model.scene = scene
|
||||
model.title = title
|
||||
model.message = message
|
||||
willLayoutSubviews()
|
||||
return self
|
||||
}
|
||||
|
||||
/// 更新图标
|
||||
/// - Parameter icon: 图标
|
||||
@discardableResult func update(icon: UIImage?) -> Alert {
|
||||
model.icon = icon
|
||||
/// - Parameter callback: 回调
|
||||
func update(_ callback: ((inout Alert.ViewModel) -> Void)? = nil) {
|
||||
callback?(&vm)
|
||||
cfg.alert.reloadData(self)
|
||||
return self
|
||||
}
|
||||
|
||||
@discardableResult func animate(rotate: Bool) -> Alert {
|
||||
func animate(rotate: Bool) {
|
||||
if rotate {
|
||||
DispatchQueue.main.async {
|
||||
let ani = CABasicAnimation(keyPath: "transform.rotation.z")
|
||||
ani.toValue = M_PI*2.0
|
||||
ani.duration = 2
|
||||
ani.toValue = Double.pi * 2.0
|
||||
ani.duration = 3
|
||||
ani.repeatCount = 10000
|
||||
self.imageView?.layer.add(ani, forKey: "rotationAnimation")
|
||||
}
|
||||
} else {
|
||||
imageView?.layer.removeAllAnimations()
|
||||
}
|
||||
return self
|
||||
}
|
||||
|
||||
/// 更新按钮
|
||||
/// - Parameter index: 索引
|
||||
/// - Parameter style: 样式
|
||||
/// - Parameter title: 标题
|
||||
/// - Parameter action: 事件
|
||||
@discardableResult func update(action index: Int, style: UIAlertAction.Style, title: String?, action: (() -> Void)?) -> Alert {
|
||||
if index < self.actionStack.arrangedSubviews.count, let btn = self.actionStack.arrangedSubviews[index] as? UIButton {
|
||||
btn.setTitle(title, for: .normal)
|
||||
if let b = btn as? Button {
|
||||
b.update(style: style)
|
||||
}
|
||||
btn.layoutIfNeeded()
|
||||
if let ac = action {
|
||||
addTouchUpAction(for: btn, action: ac)
|
||||
}
|
||||
}
|
||||
return self
|
||||
}
|
||||
|
||||
/// 移除按钮
|
||||
/// - Parameter index: 索引
|
||||
@discardableResult func remove(action index: Int...) -> Alert {
|
||||
for (i, idx) in index.enumerated() {
|
||||
privRemoveAction(index: idx-i)
|
||||
}
|
||||
return self
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
@ -247,7 +186,7 @@ public extension Alert {
|
|||
/// - Parameter title: 标题
|
||||
/// - Parameter message: 正文
|
||||
/// - Parameter actions: 更多操作
|
||||
@discardableResult class func push(alert scene: Alert.Scene, title: String? = nil, message: String? = nil, actions: ((Alert) -> Void)? = nil) -> Alert {
|
||||
@discardableResult class func push(scene: Alert.Scene, title: String? = nil, message: String? = nil, actions: ((inout Alert.ViewModel) -> Void)? = nil) -> Alert {
|
||||
return Alert(scene: scene, title: title, message: message, actions: actions).push()
|
||||
}
|
||||
|
||||
|
@ -256,7 +195,7 @@ public extension Alert {
|
|||
class func alerts(_ identifier: String?) -> [Alert] {
|
||||
var aa = [Alert]()
|
||||
for a in Alert.alerts {
|
||||
if a.identifier == identifier {
|
||||
if a.vm.identifier == identifier {
|
||||
aa.append(a)
|
||||
}
|
||||
}
|
||||
|
@ -281,7 +220,7 @@ public extension Alert {
|
|||
|
||||
// MARK: - 私有
|
||||
|
||||
fileprivate extension Alert {
|
||||
internal extension Alert {
|
||||
|
||||
/// 移除按钮
|
||||
/// - Parameter index: 索引
|
||||
|
@ -298,52 +237,56 @@ fileprivate extension Alert {
|
|||
if self.actionStack.arrangedSubviews.count == 0 {
|
||||
self.actionStack.removeFromSuperview()
|
||||
}
|
||||
willLayoutSubviews()
|
||||
UIView.animateForAlert {
|
||||
self.view.layoutIfNeeded()
|
||||
}
|
||||
return self
|
||||
}
|
||||
|
||||
func willLayoutSubviews() {
|
||||
model.setupWillLayout(duration: 0.001) { [weak self] in
|
||||
if let a = self {
|
||||
// 布局
|
||||
cfg.alert.loadSubviews(a)
|
||||
cfg.alert.reloadData(a)
|
||||
cfg.alert.setupDefaultDuration(a)
|
||||
// 强制退出按钮
|
||||
a.model.setupForceQuit(duration: cfg.alert.forceQuitTimer) { [weak self] in
|
||||
if let aa = self, aa.actionStack.superview == nil {
|
||||
cfg.alert.loadForceQuitButton(aa)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@discardableResult func privAddButton(custom button: UIButton, action: (() -> Void)?) -> UIButton {
|
||||
model.duration = nil
|
||||
@discardableResult func privAddButton(custom button: UIButton, at index: Int? = nil, handler: (() -> Void)?) -> UIButton {
|
||||
if actionStack.superview == nil {
|
||||
contentStack.addArrangedSubview(actionStack)
|
||||
contentStack.layoutIfNeeded()
|
||||
}
|
||||
self.view.layoutIfNeeded()
|
||||
button.transform = .init(scaleX: 1, y: 0.001)
|
||||
if let idx = index, idx < actionStack.arrangedSubviews.count {
|
||||
actionStack.insertArrangedSubview(button, at: idx)
|
||||
} else {
|
||||
actionStack.addArrangedSubview(button)
|
||||
UIView.animateForAlert {
|
||||
button.transform = .identity
|
||||
self.view.layoutIfNeeded()
|
||||
}
|
||||
|
||||
addTouchUpAction(for: button) { [weak self] in
|
||||
action?()
|
||||
handler?()
|
||||
if button.tag == UIAlertAction.Style.cancel.rawValue {
|
||||
self?.pop()
|
||||
}
|
||||
}
|
||||
willLayoutSubviews()
|
||||
if isLoadFinished {
|
||||
actionStack.layoutIfNeeded()
|
||||
UIView.animateForAlert {
|
||||
self.view.layoutIfNeeded()
|
||||
}
|
||||
}
|
||||
return button
|
||||
}
|
||||
|
||||
func privUpdateButton(action index: Int, style: UIAlertAction.Style, title: String?, _ handler: (() -> Void)?) {
|
||||
if index < self.actionStack.arrangedSubviews.count, let btn = self.actionStack.arrangedSubviews[index] as? UIButton {
|
||||
btn.setTitle(title, for: .normal)
|
||||
if let b = btn as? Button {
|
||||
b.update(style: style)
|
||||
}
|
||||
if let _ = buttonEvents[btn] {
|
||||
buttonEvents.removeValue(forKey: btn)
|
||||
}
|
||||
addTouchUpAction(for: btn) { [weak self] in
|
||||
handler?()
|
||||
if btn.tag == UIAlertAction.Style.cancel.rawValue {
|
||||
self?.pop()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
fileprivate extension Alert {
|
||||
|
|
|
@ -35,20 +35,50 @@ public extension Alert {
|
|||
|
||||
struct ViewModel {
|
||||
|
||||
/// ID标识
|
||||
public var identifier = String(Date().timeIntervalSince1970)
|
||||
|
||||
/// 使用场景
|
||||
public var scene = Scene.default
|
||||
|
||||
/// 标题
|
||||
public var title: String?
|
||||
public var title: String? {
|
||||
didSet {
|
||||
vc?.titleLabel?.text = title
|
||||
}
|
||||
}
|
||||
|
||||
/// 正文
|
||||
public var message: String?
|
||||
public var message: String? {
|
||||
didSet {
|
||||
vc?.bodyLabel?.text = message
|
||||
}
|
||||
}
|
||||
|
||||
/// 图标
|
||||
public var icon: UIImage?
|
||||
public var icon: UIImage? {
|
||||
didSet {
|
||||
vc?.imageView?.image = icon
|
||||
}
|
||||
}
|
||||
|
||||
/// 持续时间
|
||||
internal var duration: TimeInterval?
|
||||
/// 持续时间(为空代表根据场景不同的默认配置,为0代表无穷大)
|
||||
public var duration: TimeInterval? {
|
||||
didSet {
|
||||
durationBlock?.cancel()
|
||||
if let t = duration, t > 0 {
|
||||
let v = vc
|
||||
durationBlock = DispatchWorkItem(block: {
|
||||
v?.pop()
|
||||
})
|
||||
DispatchQueue.main.asyncAfter(deadline: .now()+t, execute: durationBlock!)
|
||||
} else {
|
||||
durationBlock = nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public weak var vc: Alert?
|
||||
|
||||
/// 持续时间
|
||||
internal var durationBlock: DispatchWorkItem?
|
||||
|
@ -59,40 +89,56 @@ public extension Alert {
|
|||
/// 强制退出代码
|
||||
internal var forceQuitCallback: (() -> Void)?
|
||||
|
||||
internal var willLayoutBlock: DispatchWorkItem?
|
||||
|
||||
internal mutating func setupDuration(duration: TimeInterval?, callback: @escaping () -> Void) {
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public extension Alert.ViewModel {
|
||||
|
||||
/// 添加按钮
|
||||
/// - Parameter style: 样式
|
||||
/// - Parameter text: 标题
|
||||
/// - Parameter handler: 事件处理
|
||||
@discardableResult mutating func add(action style: UIAlertAction.Style, title: String?, handler: (() -> Void)?) -> UIButton {
|
||||
duration = 0
|
||||
let btn = vc?.privAddButton(custom: Alert.Button.actionButton(title: title), handler: handler)
|
||||
if let b = btn as? Alert.Button {
|
||||
b.update(style: style)
|
||||
}
|
||||
return btn!
|
||||
}
|
||||
|
||||
/// 插入按钮
|
||||
/// - Parameter index: 索引
|
||||
/// - Parameter style: 样式
|
||||
/// - Parameter title: 标题
|
||||
/// - Parameter handler: 事件处理
|
||||
@discardableResult mutating func insert(action index: Int, style: UIAlertAction.Style, title: String?, handler: (() -> Void)?) -> UIButton {
|
||||
duration = 0
|
||||
let btn = vc?.privAddButton(custom: Alert.Button.actionButton(title: title), at: index, handler: handler)
|
||||
if let b = btn as? Alert.Button {
|
||||
b.update(style: style)
|
||||
}
|
||||
return btn!
|
||||
}
|
||||
|
||||
/// 更新按钮
|
||||
/// - Parameter index: 索引
|
||||
/// - Parameter style: 样式
|
||||
/// - Parameter title: 标题
|
||||
/// - Parameter handler: 事件处理
|
||||
mutating func update(action index: Int, style: UIAlertAction.Style, title: String?, handler: (() -> Void)?) {
|
||||
vc?.privUpdateButton(action: index, style: style, title: title, handler)
|
||||
}
|
||||
|
||||
/// 移除按钮
|
||||
/// - Parameter index: 索引
|
||||
mutating func remove(action index: Int...) {
|
||||
guard let alert = self.vc else { return }
|
||||
for (i, idx) in index.enumerated() {
|
||||
alert.privRemoveAction(index: idx-i)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -24,6 +24,7 @@ internal extension Alert {
|
|||
backgroundColor = cfg.dynamicColor.withAlphaComponent(0.04)
|
||||
contentEdgeInsets = .init(top: pd*1.5, left: pd*1.5, bottom: pd*1.5, right: pd*1.5)
|
||||
} else {
|
||||
backgroundColor = .clear
|
||||
contentEdgeInsets = .init(top: pd*0.5, left: pd*1.5, bottom: pd*0.5, right: pd*1.5)
|
||||
}
|
||||
switch style {
|
||||
|
|
|
@ -86,11 +86,7 @@ fileprivate var privLoadSubviews: (ProHUD.Guard) -> Void = {
|
|||
return { (vc) in
|
||||
debug(vc, "loadSubviews")
|
||||
let config = cfg.guard
|
||||
// background
|
||||
vc.view.tintColor = config.tintColor
|
||||
vc.view.backgroundColor = UIColor(white: 0, alpha: 0)
|
||||
vc.view.addSubview(vc.contentView)
|
||||
vc.contentView.contentView.addSubview(vc.contentStack)
|
||||
|
||||
}
|
||||
}()
|
||||
|
||||
|
@ -98,6 +94,11 @@ fileprivate var privReloadData: (ProHUD.Guard) -> Void = {
|
|||
return { (vc) in
|
||||
debug(vc, "reloadData")
|
||||
let config = cfg.guard
|
||||
// background
|
||||
vc.view.tintColor = config.tintColor
|
||||
vc.view.backgroundColor = UIColor(white: 0, alpha: 0)
|
||||
vc.view.addSubview(vc.contentView)
|
||||
vc.contentView.contentView.addSubview(vc.contentStack)
|
||||
// 更新布局
|
||||
var width = UIScreen.main.bounds.width
|
||||
if width > config.cardMaxWidth {
|
||||
|
|
|
@ -50,23 +50,26 @@ public extension ProHUD {
|
|||
/// 背景颜色
|
||||
public var backgroundColor: UIColor? = UIColor(white: 0, alpha: 0.5)
|
||||
|
||||
public var vm = ViewModel()
|
||||
|
||||
// MARK: 生命周期
|
||||
|
||||
/// 实例化
|
||||
/// - Parameter title: 标题
|
||||
/// - Parameter message: 内容
|
||||
/// - Parameter actions: 更多操作
|
||||
public convenience init(title: String? = nil, message: String? = nil, actions: ((Guard) -> Void)? = nil) {
|
||||
public convenience init(title: String? = nil, message: String? = nil, actions: ((inout ViewModel) -> Void)? = nil) {
|
||||
self.init()
|
||||
|
||||
view.tintColor = cfg.guard.tintColor
|
||||
vm.vc = self
|
||||
if let _ = title {
|
||||
add(title: title)
|
||||
}
|
||||
if let _ = message {
|
||||
add(message: message)
|
||||
}
|
||||
actions?(self)
|
||||
actions?(&vm)
|
||||
|
||||
view.tintColor = cfg.guard.tintColor
|
||||
cfg.guard.loadSubviews(self)
|
||||
cfg.guard.reloadData(self)
|
||||
cfg.guard.reloadStack(self)
|
||||
|
@ -91,7 +94,7 @@ public extension Guard {
|
|||
|
||||
/// 推入某个视图控制器
|
||||
/// - Parameter viewController: 视图控制器
|
||||
func push(to viewController: UIViewController? = nil) -> Guard {
|
||||
@discardableResult func push(to viewController: UIViewController? = nil) -> Guard {
|
||||
func f(_ vc: UIViewController) {
|
||||
view.layoutIfNeeded()
|
||||
vc.addChild(self)
|
||||
|
@ -226,7 +229,7 @@ public extension Guard {
|
|||
/// - Parameter title: 标题
|
||||
/// - Parameter message: 正文
|
||||
/// - Parameter icon: 图标
|
||||
@discardableResult class func push(to viewController: UIViewController? = nil, actions: ((Guard) -> Void)? = nil) -> Guard {
|
||||
@discardableResult class func push(to viewController: UIViewController? = nil, actions: ((inout ViewModel) -> Void)? = nil) -> Guard {
|
||||
return Guard(actions: actions).push(to: viewController)
|
||||
}
|
||||
|
||||
|
@ -239,7 +242,7 @@ public extension Guard {
|
|||
if child.isKind(of: Guard.self) {
|
||||
if let g = child as? Guard {
|
||||
if let id = identifier {
|
||||
if g.identifier == id {
|
||||
if g.vm.identifier == id {
|
||||
gg.append(g)
|
||||
}
|
||||
} else {
|
||||
|
@ -272,7 +275,7 @@ public extension Guard {
|
|||
|
||||
// MARK: - 私有
|
||||
|
||||
fileprivate extension Guard {
|
||||
internal extension Guard {
|
||||
|
||||
/// 点击事件
|
||||
/// - Parameter sender: 手势
|
||||
|
@ -317,6 +320,5 @@ fileprivate extension Guard {
|
|||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,80 @@
|
|||
//
|
||||
// GuardModel.swift
|
||||
// ProHUD
|
||||
//
|
||||
// Created by xaoxuu on 2019/8/9.
|
||||
// Copyright © 2019 Titan Studio. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
|
||||
public extension Guard {
|
||||
|
||||
struct ViewModel {
|
||||
|
||||
/// ID标识
|
||||
public var identifier = String(Date().timeIntervalSince1970)
|
||||
|
||||
public weak var vc: Guard?
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public extension Guard.ViewModel {
|
||||
|
||||
/// 加载一个标题
|
||||
/// - Parameter text: 文本
|
||||
@discardableResult func add(title: String?) -> UILabel {
|
||||
return vc!.add(title: title)
|
||||
}
|
||||
|
||||
/// 加载一个副标题
|
||||
/// - Parameter text: 文本
|
||||
@discardableResult func add(subTitle: String?) -> UILabel {
|
||||
return vc!.add(subTitle: subTitle)
|
||||
}
|
||||
|
||||
/// 加载一段正文
|
||||
/// - Parameter text: 文本
|
||||
@discardableResult func add(message: String?) -> UILabel {
|
||||
return vc!.add(message: message)
|
||||
}
|
||||
|
||||
/// 加载一个按钮
|
||||
/// - Parameter style: 样式
|
||||
/// - Parameter title: 标题
|
||||
/// - Parameter action: 事件
|
||||
@discardableResult func add(action style: UIAlertAction.Style, title: String?, handler: (() -> Void)?) -> UIButton {
|
||||
return vc!.add(action: style, title: title, handler: handler)
|
||||
}
|
||||
|
||||
/// 插入按钮
|
||||
/// - Parameter index: 索引
|
||||
/// - Parameter style: 样式
|
||||
/// - Parameter title: 标题
|
||||
/// - Parameter handler: 事件处理
|
||||
@discardableResult mutating func insert(action index: Int, style: UIAlertAction.Style, title: String?, handler: (() -> Void)?) -> UIButton {
|
||||
|
||||
return UIButton()
|
||||
}
|
||||
|
||||
/// 更新按钮
|
||||
/// - Parameter index: 索引
|
||||
/// - Parameter style: 样式
|
||||
/// - Parameter title: 标题
|
||||
/// - Parameter handler: 事件处理
|
||||
mutating func update(action index: Int, style: UIAlertAction.Style, title: String?, handler: (() -> Void)?) {
|
||||
// vc?.privUpdateButton(action: index, style: style, title: title, handler)
|
||||
}
|
||||
|
||||
/// 移除按钮
|
||||
/// - Parameter index: 索引
|
||||
func remove(action index: Int...) {
|
||||
for (i, idx) in index.enumerated() {
|
||||
vc!.privRemoveAction(index: idx-i)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -10,9 +10,6 @@ import UIKit
|
|||
|
||||
public class HUDController: UIViewController {
|
||||
|
||||
/// ID标识
|
||||
public var identifier = String(Date().timeIntervalSince1970)
|
||||
|
||||
/// 消失回调
|
||||
internal var disappearCallback: (() -> Void)?
|
||||
|
||||
|
|
|
@ -243,7 +243,7 @@ public extension Toast {
|
|||
/// - Parameter title: 标题
|
||||
/// - Parameter message: 内容
|
||||
/// - Parameter actions: 更多操作
|
||||
@discardableResult class func push(toast scene: Toast.Scene, title: String? = nil, message: String? = nil, actions: ((Toast) -> Void)? = nil) -> Toast {
|
||||
@discardableResult class func push(scene: Toast.Scene, title: String? = nil, message: String? = nil, actions: ((Toast) -> Void)? = nil) -> Toast {
|
||||
return Toast(scene: scene, title: title, message: message, actions: actions).push()
|
||||
}
|
||||
|
||||
|
@ -252,7 +252,7 @@ public extension Toast {
|
|||
class func toasts(_ identifier: String?) -> [Toast] {
|
||||
var tt = [Toast]()
|
||||
for t in toasts {
|
||||
if t.identifier == identifier {
|
||||
if t.model.identifier == identifier {
|
||||
tt.append(t)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -35,6 +35,9 @@ public extension Toast {
|
|||
|
||||
struct ViewModel {
|
||||
|
||||
/// ID标识
|
||||
public var identifier = String(Date().timeIntervalSince1970)
|
||||
|
||||
/// 使用场景
|
||||
public var scene = Scene.default
|
||||
|
||||
|
|
Loading…
Reference in New Issue