This commit is contained in:
xaoxuu 2019-08-12 20:20:07 +08:00
parent 1a2787a2cd
commit 29fa9f13c0
11 changed files with 256 additions and 149 deletions

View File

@ -18,7 +18,7 @@ class TestAlertVC: BaseListVC {
}
override var titles: [String] {
return ["场景:正在同步(超时)", "场景:同步成功", "场景:同步失败和重试"]
return ["场景:正在同步(超时)", "场景:同步成功写法1", "场景同步成功写法2", "场景:同步失败和重试"]
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
@ -26,9 +26,8 @@ class TestAlertVC: BaseListVC {
let row = indexPath.row
if row == 0 {
func f() {
let a = Alert.push(scene: .loading, title: "正在同步", message: "请稍等片刻") { (vm) in
vm.identifier = "loading"
}
Alert.push(scene: .loading, title: "正在同步", message: "请稍等片刻") { (a) in
a.identifier = "loading"
a.animate(rotate: true)
a.didForceQuit { [weak self] in
let t = Toast.push(scene: .loading, title: "正在同步", message: "请稍等片刻点击展开为Alert") { (vm) in
@ -41,28 +40,54 @@ class TestAlertVC: BaseListVC {
}
self?.simulateSync()
}
}
simulateSync()
}
f()
} else if row == 1 {
Alert.push(scene: .loading, title: "正在同步", message: "请稍等片刻") { (vm) in
vm.identifier = "loading"
}.animate(rotate: true)
Alert.push() { (a) in
a.identifier = "loading"
a.animate(rotate: true)
a.update { (vm) in
vm.scene = .loading
vm.title = "正在同步"
vm.message = "请稍等片刻"
}
}
DispatchQueue.main.asyncAfter(deadline: .now()+2) {
if let a = Alert.get("loading").last {
Alert.find("loading", last: { (a) in
a.update { (vm) in
vm.scene = .success
vm.title = "同步成功"
vm.message = nil
}
}
})
}
} else if row == 2 {
Alert.push() { (vm) in
vm.identifier = "loading"
let a = Alert.push() { (a) in
a.identifier = "loading"
}
a.animate(rotate: true)
a.update { (vm) in
vm.scene = .loading
vm.title = "正在同步"
vm.message = "请稍等片刻"
}
DispatchQueue.main.asyncAfter(deadline: .now()+2) {
Alert.find("loading", last: { (a) in
a.update { (vm) in
vm.scene = .success
vm.title = "同步成功"
vm.message = nil
}
})
}
} else if row == 3 {
Alert.push() { (a) in
a.identifier = "loading"
}
func loading() {
if let a = Alert.get("loading").last {
Alert.find("loading", last: { (a) in
a.update { (vm) in
vm.scene = .loading
vm.title = "正在同步"
@ -81,7 +106,7 @@ class TestAlertVC: BaseListVC {
vm.add(action: .cancel, title: "取消", handler: nil)
}
}
}
})
}
loading()
}
@ -89,13 +114,13 @@ class TestAlertVC: BaseListVC {
func simulateSync() {
DispatchQueue.main.asyncAfter(deadline: .now() + 15) {
if let t = Alert.get("loading").last {
t.update { (vm) in
Alert.find("loading", last: { (a) in
a.update { (vm) in
vm.scene = .success
vm.title = "同步成功"
vm.message = "啊哈哈哈哈哈哈哈哈"
}
}
})
}
}

View File

@ -26,34 +26,37 @@ class TestGuardVC: BaseListVC {
tableView.deselectRow(at: indexPath, animated: true)
let row = indexPath.row
if row == 0 {
Guard.push() { (vm) in
let vc = vm.vc
Guard.push() { (vc) in
vc.update { (vm) in
vm.add(action: .destructive, title: "删除") { [weak vc] in
Alert.push(scene: .delete, title: "确认删除", message: "此操作不可撤销") { (vm) in
let vc = vm.vc
Alert.push(scene: .delete, title: "确认删除", message: "此操作不可撤销") { (vc) in
vc.update { (vm) in
vm.add(action: .destructive, title: "删除") { [weak vc] in
vc?.pop()
}
vm.add(action: .cancel, title: "取消", handler: nil)
}
}
vc?.pop()
}
vm.add(action: .cancel, title: "取消", handler: nil)
}
}
} else if row == 1 {
// id
if Guard.get("pro").count == 0 {
Guard.push() { (vm) in
let vc = vm.vc
vm.identifier = "pro"
Guard.find("pro") {
Guard.push() { (vc) in
vc.identifier = "pro"
vc.update { (vm) in
vm.add(title: "升级至专业版")
vm.add(subTitle: "解锁功能")
vm.add(message: "功能1功能2...")
vm.add(subTitle: "价格")
vm.add(message: "只需一次性付费$2999即可永久享用。")
vm.add(action: .destructive, title: "购买") { [weak vc] in
Alert.push(scene: .confirm, title: "确认购买", message: "一旦购买拒不退款") { (vm) in
let vc = vm.vc
Alert.push(scene: .confirm, title: "确认购买", message: "一旦购买拒不退款") { (vc) in
vc.identifier = "confirm"
vc.update { (vm) in
vm.add(action: .destructive, title: "购买") { [weak vc] in
vc?.update({ (vm) in
vm.scene = .success
@ -67,16 +70,17 @@ class TestGuardVC: BaseListVC {
}
vm.add(action: .cancel, title: "取消", handler: nil)
}
}
vc?.pop()
}
vm.add(action: .cancel, title: "取消", handler: nil)
}
}
}
} else if row == 2 {
Guard.push() { (vm) in
let vc = vm.vc
vc?.isFullScreen = true
Guard.push() { (vc) in
vc.isFullScreen = true
vc.update { (vm) in
let titleLabel = vm.add(title: "隐私协议")
titleLabel.snp.makeConstraints { (mk) in
mk.height.equalTo(44)
@ -84,13 +88,14 @@ class TestGuardVC: BaseListVC {
let tv = UITextView()
tv.backgroundColor = .white
tv.isEditable = false
vc?.textStack.addArrangedSubview(tv)
vc.textStack.addArrangedSubview(tv)
tv.text = "这里可以插入一个webView"
vm.add(message: "请认真阅读以上内容,当您阅读完毕并同意协议内容时点击接受按钮。")
vm.add(action: .default, title: "接受") { [weak vc] in
vc?.pop()
}
}
}

View File

@ -24,7 +24,9 @@ class TestToastVC: BaseListVC {
"场景:设备电量过低",
"传入指定图标",
"禁止手势移除",
"组合使用示例"]
"组合使用示例",
"避免重复发布同一条信息",
"根据id查找并修改实例"]
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
@ -42,34 +44,39 @@ class TestToastVC: BaseListVC {
t?.pop()
}
} else if row == 2 {
let t = Toast.push(scene: .error, title: "同步失败", message: "请稍后重试。点击查看详情") { (vm) in
Toast.push(scene: .error, title: "同步失败", message: "请稍后重试。点击查看详情") { (vc) in
vc.update { (vm) in
vm.duration = 0
}
t.didTapped { [weak self, weak t] in
vc.didTapped { [weak self, weak vc] in
self?.presentEmptyVC(title: "这是错误详情")
t?.pop()
vc?.pop()
}
}
} else if row == 3 {
Toast.push(scene: .warning, title: "设备电量过低", message: "请及时对设备进行充电,以免影响使用。")
} else if row == 4 {
Toast.push(scene: .default, title: "传入指定图标测试", message: "这是消息内容") { (vm) in
Toast.push(scene: .default, title: "传入指定图标测试", message: "这是消息内容") { (vc) in
vc.update { (vm) in
vm.icon = UIImage(named: "icon_download")
}
}
} else if row == 5 {
Toast.push(scene: .default, title: "禁止手势移除", message: "这条消息无法通过向上滑动移出屏幕。5秒后自动消失每次拖拽都会刷新倒计时。") { (vm) in
Toast.push(scene: .default, title: "禁止手势移除", message: "这条消息无法通过向上滑动移出屏幕。5秒后自动消失每次拖拽都会刷新倒计时。") { (vc) in
vc.update { (vm) in
vm.isRemovable = false
vm.duration = 5
}
}
} else if row == 6 {
let t = Toast.push(scene: .default, title: "好友邀请", message: "你收到一条好友邀请,点击查看详情。", duration: 10)
t.didTapped { [weak t] in
t?.pop()
Alert.push(scene: .confirm, title: "好友邀请", message: "用户xxx想要添加你为好友是否同意") { (vm) in
let vc = vm.vc
vm.add(action: .default, title: "接受") {
Toast.push(scene: .default, title: "好友邀请", message: "你收到一条好友邀请,点击查看详情。", duration: 10) { (vc) in
vc.identifier = "xxx"
vc.didTapped { [weak vc] in
vc?.pop()
Alert.push(scene: .confirm, title: "好友邀请", message: "用户xxx想要添加你为好友是否同意") { (vc) in
vc.update { (vm) in
vm.add(action: .default, title: "接受") { [weak vc] in
vc?.pop()
Toast.push(scene: .success, title: "好友添加成功", message: "这是消息内容")
}
@ -79,18 +86,42 @@ class TestToastVC: BaseListVC {
}
}
}
}
} else if row == 7 {
Toast.find("aaa", last: { (t) in
t.update { (vm) in
vm.title = "已经存在了"
}
}) {
Toast.push(title: "这是一条id为aaa的横幅", message: "避免重复发布同一条信息") { (t) in
t.identifier = "aaa"
t.update { (vm) in
vm.scene = .warning
vm.duration = 0
}
}
}
} else if row == 8 {
Toast.find("aaa", last: { (t) in
t.update { (vm) in
vm.scene = .success
vm.title = "找到了哈哈"
vm.message = "根据id查找并修改实例"
}
})
}
}
func simulateSync() {
DispatchQueue.main.asyncAfter(deadline: .now() + 5) {
if let t = Toast.get("loading").last {
Toast.find("loading", last: { (t) in
t.update { (vm) in
vm.scene = .success
vm.title = "同步成功"
vm.message = "啊哈哈哈哈哈哈哈哈"
}
}
})
}
}

View File

@ -15,7 +15,7 @@ class ViewController: BaseListVC {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
title = "ProHUD"
}
override var titles: [String] {
@ -25,11 +25,17 @@ class ViewController: BaseListVC {
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath, animated: true)
if indexPath.row == 0 {
navigationController?.pushViewController(TestToastVC(), animated: true)
let vc = TestToastVC()
vc.title = titles[indexPath.row]
navigationController?.pushViewController(vc, animated: true)
} else if indexPath.row == 1 {
navigationController?.pushViewController(TestAlertVC(), animated: true)
let vc = TestAlertVC()
vc.title = titles[indexPath.row]
navigationController?.pushViewController(vc, animated: true)
} else {
navigationController?.pushViewController(TestGuardVC(), animated: true)
let vc = TestGuardVC()
vc.title = titles[indexPath.row]
navigationController?.pushViewController(vc, animated: true)
}
}

View File

@ -63,14 +63,14 @@ public extension ProHUD {
/// - Parameter title:
/// - Parameter message:
/// - Parameter icon:
public convenience init(scene: Scene = .default, title: String? = nil, message: String? = nil, icon: UIImage? = nil, actions: ((inout ViewModel) -> Void)? = nil) {
public convenience init(scene: Scene = .default, title: String? = nil, message: String? = nil, icon: UIImage? = nil, actions: ((Alert) -> Void)? = nil) {
self.init()
vm.vc = self
vm.scene = scene
vm.title = title
vm.message = message
vm.icon = icon
actions?(&vm)
actions?(self)
}
public override func viewDidLoad() {
@ -176,22 +176,34 @@ public extension Alert {
/// - Parameter title:
/// - Parameter message:
/// - Parameter actions:
@discardableResult class func push(scene: Alert.Scene = .default, title: String? = nil, message: String? = nil, _ actions: ((inout ViewModel) -> Void)? = nil) -> Alert {
@discardableResult class func push(scene: Alert.Scene = .default, title: String? = nil, message: String? = nil, _ actions: ((Alert) -> Void)? = nil) -> Alert {
return Alert(scene: scene, title: title, message: message, actions: actions).push()
}
///
/// - Parameter identifier:
class func get(_ identifier: String?) -> [Alert] {
class func find(_ identifier: String?) -> [Alert] {
var aa = [Alert]()
for a in Alert.alerts {
if a.vm.identifier == identifier {
if a.identifier == identifier {
aa.append(a)
}
}
return aa
}
///
/// - Parameter identifier:
/// - Parameter last:
/// - Parameter none:
class func find(_ identifier: String?, last: ((Alert) -> Void)? = nil, none: (() -> Void)? = nil) {
if let t = find(identifier).last {
last?(t)
} else {
none?()
}
}
///
/// - Parameter alert:
class func pop(_ alert: Alert) {
@ -201,7 +213,7 @@ public extension Alert {
///
/// - Parameter identifier:
class func pop(_ identifier: String?) {
for a in get(identifier) {
for a in find(identifier) {
a.pop()
}
}
@ -212,8 +224,7 @@ public extension Alert {
// MARK: -
internal extension Alert {
///
///
/// - Parameter style:
/// - Parameter title:
/// - Parameter action:
@ -244,6 +255,11 @@ internal extension Alert {
return btn
}
///
/// - Parameter index:
/// - Parameter style:
/// - Parameter title:
/// - Parameter handler:
func update(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)

View File

@ -35,9 +35,6 @@ public extension Alert {
class ViewModel {
/// ID
public var identifier = String(Date().timeIntervalSince1970)
/// 使
public var scene = Scene.default

View File

@ -63,7 +63,7 @@ public extension ProHUD {
/// - Parameter title:
/// - Parameter message:
/// - Parameter actions:
public convenience init(title: String? = nil, message: String? = nil, actions: ((inout ViewModel) -> Void)? = nil) {
public convenience init(title: String? = nil, message: String? = nil, actions: ((Guard) -> Void)? = nil) {
self.init()
vm.vc = self
if let _ = title {
@ -72,7 +72,7 @@ public extension ProHUD {
if let _ = message {
add(message: message)
}
actions?(&vm)
actions?(self)
//
let tap = UITapGestureRecognizer(target: self, action: #selector(privDidTapped(_:)))
@ -158,20 +158,20 @@ public extension Guard {
/// - Parameter title:
/// - Parameter message:
/// - Parameter icon:
@discardableResult class func push(to viewController: UIViewController? = nil, _ actions: ((inout ViewModel) -> Void)? = nil) -> Guard {
@discardableResult class func push(to viewController: UIViewController? = nil, _ actions: ((Guard) -> Void)? = nil) -> Guard {
return Guard(actions: actions).push(to: viewController)
}
///
/// - Parameter identifier:
class func get(_ identifier: String? = nil, from viewController: UIViewController? = nil) -> [Guard] {
class func find(_ identifier: String?, from viewController: UIViewController? = nil) -> [Guard] {
var gg = [Guard]()
if let vc = viewController ?? cfg.rootViewController {
for child in vc.children {
if child.isKind(of: Guard.self) {
if let g = child as? Guard {
if let id = identifier {
if g.vm.identifier == id {
if g.identifier == id {
gg.append(g)
}
} else {
@ -184,6 +184,19 @@ public extension Guard {
return gg
}
///
/// - Parameter identifier:
/// - Parameter last:
/// - Parameter none:
class func find(_ identifier: String?, from viewController: UIViewController? = nil, last: ((Guard) -> Void)? = nil, none: (() -> Void)? = nil) {
if let t = find(identifier, from: viewController).last {
last?(t)
} else {
none?()
}
}
///
/// - Parameter alert:
class func pop(_ guard: Guard) {
@ -192,8 +205,8 @@ public extension Guard {
///
/// - Parameter identifier:
class func pop(from viewController: UIViewController?) {
for g in get(from: viewController) {
class func pop(_ identifier: String?, from viewController: UIViewController?) {
for g in find(identifier, from: viewController) {
g.pop()
}
}
@ -250,7 +263,7 @@ internal extension Guard {
return lb
}
///
///
/// - Parameter index:
/// - Parameter style:
/// - Parameter title:
@ -278,6 +291,12 @@ internal extension Guard {
}
return btn
}
///
/// - Parameter index:
/// - Parameter style:
/// - Parameter title:
/// - Parameter handler:
func update(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)
@ -321,7 +340,6 @@ internal extension Guard {
return self
}
}
fileprivate extension Guard {

View File

@ -10,12 +10,9 @@ import UIKit
public extension Guard {
class ViewModel {
struct ViewModel {
/// ID
public var identifier = String(Date().timeIntervalSince1970)
public weak var vc: Guard?
internal weak var vc: Guard?
}
@ -49,7 +46,7 @@ public extension Guard.ViewModel {
return vc!.insert(action: nil, style: style, title: title, handler: handler)
}
///
///
/// - Parameter index:
/// - Parameter style:
/// - Parameter title:

View File

@ -10,6 +10,9 @@ import UIKit
public class HUDController: UIViewController {
/// ID
public var identifier = String(Date().timeIntervalSince1970)
internal var willAppearCallback: (() -> Void)?
internal var didAppearCallback: (() -> Void)?
internal var willDisappearCallback: (() -> Void)?

View File

@ -65,7 +65,7 @@ public extension ProHUD {
/// - Parameter title:
/// - Parameter message:
/// - Parameter icon:
public convenience init(scene: Scene = .default, title: String? = nil, message: String? = nil, icon: UIImage? = nil, duration: TimeInterval? = nil, actions: ((inout ViewModel) -> Void)? = nil) {
public convenience init(scene: Scene = .default, title: String? = nil, message: String? = nil, icon: UIImage? = nil, duration: TimeInterval? = nil, actions: ((Toast) -> Void)? = nil) {
self.init()
vm.vc = self
@ -74,7 +74,7 @@ public extension ProHUD {
vm.message = message
vm.icon = icon
vm.duration = duration
actions?(&vm)
actions?(self)
//
let tap = UITapGestureRecognizer(target: self, action: #selector(privDidTapped(_:)))
@ -198,22 +198,34 @@ public extension Toast {
/// - Parameter title:
/// - Parameter message:
/// - Parameter actions:
@discardableResult class func push(scene: Toast.Scene = .default, title: String? = nil, message: String? = nil, duration: TimeInterval? = nil, _ actions: ((inout ViewModel) -> Void)? = nil) -> Toast {
@discardableResult class func push(scene: Toast.Scene = .default, title: String? = nil, message: String? = nil, duration: TimeInterval? = nil, _ actions: ((Toast) -> Void)? = nil) -> Toast {
return Toast(scene: scene, title: title, message: message, duration: duration, actions: actions).push()
}
/// toast
/// - Parameter identifier:
class func get(_ identifier: String?) -> [Toast] {
class func find(_ identifier: String?) -> [Toast] {
var tt = [Toast]()
for t in toasts {
if t.vm.identifier == identifier {
if t.identifier == identifier {
tt.append(t)
}
}
return tt
}
///
/// - Parameter identifier:
/// - Parameter last:
/// - Parameter none:
class func find(_ identifier: String?, last: ((Toast) -> Void)? = nil, none: (() -> Void)? = nil) {
if let t = find(identifier).last {
last?(t)
} else {
none?()
}
}
///
/// - Parameter toast:
class func pop(_ toast: Toast) {
@ -242,7 +254,7 @@ public extension Toast {
///
/// - Parameter identifier:
class func pop(_ identifier: String?) {
for t in get(identifier) {
for t in find(identifier) {
t.pop()
}
}

View File

@ -29,9 +29,6 @@ public extension Toast {
class ViewModel {
/// ID
public var identifier = String(Date().timeIntervalSince1970)
/// 使
public var scene = Scene.default