diff --git a/Example/Example.xcodeproj/project.pbxproj b/Example/Example.xcodeproj/project.pbxproj index 61798b7..e6c595e 100644 --- a/Example/Example.xcodeproj/project.pbxproj +++ b/Example/Example.xcodeproj/project.pbxproj @@ -8,6 +8,7 @@ /* Begin PBXBuildFile section */ 33E2B6CF0D9BD11D8C027DE6 /* Pods_Example.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AB925B38880FB296AF5D219F /* Pods_Example.framework */; }; + CD4B40AA23017C09005111B9 /* RootVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD4B40A923017C09005111B9 /* RootVC.swift */; }; CD8BFF1823014850001E08DD /* TestToastVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD8BFF1723014850001E08DD /* TestToastVC.swift */; }; CD8BFF1A2301485E001E08DD /* TestAlertVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD8BFF192301485E001E08DD /* TestAlertVC.swift */; }; CD8BFF1C23014867001E08DD /* TestGuardVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD8BFF1B23014867001E08DD /* TestGuardVC.swift */; }; @@ -24,6 +25,7 @@ AB925B38880FB296AF5D219F /* Pods_Example.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Example.framework; sourceTree = BUILT_PRODUCTS_DIR; }; BA1A6035F1B9A658B3BB225C /* Pods-Example.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Example.release.xcconfig"; path = "Pods/Target Support Files/Pods-Example/Pods-Example.release.xcconfig"; sourceTree = ""; }; CA1298266BE89D7950DE99F2 /* Pods-Example.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Example.debug.xcconfig"; path = "Pods/Target Support Files/Pods-Example/Pods-Example.debug.xcconfig"; sourceTree = ""; }; + CD4B40A923017C09005111B9 /* RootVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RootVC.swift; sourceTree = ""; }; CD59584620E36DA8000F6427 /* Example-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Example-Bridging-Header.h"; sourceTree = ""; }; CD8BFF1723014850001E08DD /* TestToastVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TestToastVC.swift; sourceTree = ""; }; CD8BFF192301485E001E08DD /* TestAlertVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TestAlertVC.swift; sourceTree = ""; }; @@ -90,6 +92,7 @@ isa = PBXGroup; children = ( CDA4E03B20D3935B00CD2A0C /* AppDelegate.swift */, + CD4B40A923017C09005111B9 /* RootVC.swift */, CD8BFF1D230148DD001E08DD /* BaseListVC.swift */, CD8BFF1F23014CB5001E08DD /* EmptyVC.swift */, CDA4E03D20D3935B00CD2A0C /* ViewController.swift */, @@ -242,6 +245,7 @@ CDA4E03E20D3935B00CD2A0C /* ViewController.swift in Sources */, CD8BFF2023014CB5001E08DD /* EmptyVC.swift in Sources */, CD8BFF1A2301485E001E08DD /* TestAlertVC.swift in Sources */, + CD4B40AA23017C09005111B9 /* RootVC.swift in Sources */, CDA4E03C20D3935B00CD2A0C /* AppDelegate.swift in Sources */, CD8BFF1C23014867001E08DD /* TestGuardVC.swift in Sources */, CD8BFF1E230148DD001E08DD /* BaseListVC.swift in Sources */, diff --git a/Example/Example/AppDelegate.swift b/Example/Example/AppDelegate.swift index 3acc6da..25ae9a1 100644 --- a/Example/Example/AppDelegate.swift +++ b/Example/Example/AppDelegate.swift @@ -9,8 +9,6 @@ import UIKit import ProHUD -let hud = ProHUD.shared - @UIApplicationMain class AppDelegate: UIResponder, UIApplicationDelegate { @@ -20,7 +18,30 @@ class AppDelegate: UIResponder, UIApplicationDelegate { func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { // Override point for customization after application launch. - + window = UIWindow.init(frame: UIScreen.main.bounds) + window?.rootViewController = RootVC() + window?.makeKeyAndVisible() + + ProHUD.config { (cfg) in + cfg.rootViewController = window!.rootViewController + cfg.alert { (a) in + a.titleFont = .bold(22) + a.bodyFont = .regular(17) + a.boldTextFont = .bold(18) + a.buttonFont = .bold(18) + a.forceQuitTimer = 3 + } + cfg.toast { (t) in + t.titleFont = .bold(18) + t.bodyFont = .regular(16) + } + cfg.guard { (g) in + g.titleFont = .bold(22) + g.subTitleFont = .bold(20) + g.bodyFont = .regular(17) + g.buttonFont = .bold(18) + } + } return true } diff --git a/Example/Example/RootVC.swift b/Example/Example/RootVC.swift new file mode 100644 index 0000000..8a34a89 --- /dev/null +++ b/Example/Example/RootVC.swift @@ -0,0 +1,34 @@ +// +// RootVC.swift +// Example +// +// Created by xaoxuu on 2019/8/12. +// Copyright © 2019 Titan Studio. All rights reserved. +// + +import UIKit + +class RootVC: UIViewController { + + override func viewDidLoad() { + super.viewDidLoad() + + // Do any additional setup after loading the view. + let vc = ViewController() + let nav = UINavigationController(rootViewController: vc) + addChild(nav) + view.addSubview(nav.view) + } + + + /* + // MARK: - Navigation + + // In a storyboard-based application, you will often want to do a little preparation before navigation + override func prepare(for segue: UIStoryboardSegue, sender: Any?) { + // Get the new view controller using segue.destination. + // Pass the selected object to the new view controller. + } + */ + +} diff --git a/Example/Example/TestGuardVC.swift b/Example/Example/TestGuardVC.swift index d5e6278..115199d 100644 --- a/Example/Example/TestGuardVC.swift +++ b/Example/Example/TestGuardVC.swift @@ -26,12 +26,12 @@ class TestGuardVC: BaseListVC { tableView.deselectRow(at: indexPath, animated: true) let row = indexPath.row if row == 0 { - Guard.push(to: self.navigationController) { (vm) in + Guard.push() { (vm) in let vc = vm.vc - vm.add(action: .destructive, title: "删除") { + vm.add(action: .destructive, title: "删除") { [weak vc] in Alert.push(scene: .delete, title: "确认删除", message: "此操作不可撤销") { (vm) in let vc = vm.vc - vm.add(action: .destructive, title: "删除") { + vm.add(action: .destructive, title: "删除") { [weak vc] in vc?.pop() } vm.add(action: .cancel, title: "取消", handler: nil) @@ -42,8 +42,8 @@ class TestGuardVC: BaseListVC { } } else if row == 1 { // 可以通过id来避免重复 - if Guard.get("pro", from: self.navigationController).count == 0 { - Guard.push(to: self.navigationController) { (vm) in + if Guard.get("pro").count == 0 { + Guard.push() { (vm) in let vc = vm.vc vm.identifier = "pro" vm.add(title: "升级至专业版") @@ -74,7 +74,7 @@ class TestGuardVC: BaseListVC { } } else if row == 2 { - let g = Guard.push(to: self.navigationController) { (vm) in + Guard.push() { (vm) in let vc = vm.vc vc?.isFullScreen = true let titleLabel = vm.add(title: "隐私协议") @@ -83,6 +83,7 @@ class TestGuardVC: BaseListVC { } let tv = UITextView() tv.backgroundColor = .white + tv.isEditable = false vc?.textStack.addArrangedSubview(tv) tv.text = "这里可以插入一个webView" vm.add(message: "请认真阅读以上内容,当您阅读完毕并同意协议内容时点击接受按钮。") diff --git a/Example/Example/TestToastVC.swift b/Example/Example/TestToastVC.swift index 266b184..b4f30d5 100644 --- a/Example/Example/TestToastVC.swift +++ b/Example/Example/TestToastVC.swift @@ -59,7 +59,7 @@ class TestToastVC: BaseListVC { } } else if row == 5 { Toast.push(scene: .default, title: "禁止手势移除", message: "这条消息无法通过向上滑动移出屏幕。5秒后自动消失,每次拖拽都会刷新倒计时。") { (vm) in - vm.removable = false + vm.isRemovable = false vm.duration = 5 } } else if row == 6 { diff --git a/Example/Example/ViewController.swift b/Example/Example/ViewController.swift index c46bb40..05145a9 100644 --- a/Example/Example/ViewController.swift +++ b/Example/Example/ViewController.swift @@ -12,39 +12,10 @@ import SnapKit class ViewController: BaseListVC { - override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view. - - ProHUD.config { (cfg) in - cfg.rootViewController = self - - cfg.alert { (a) in - -// a.durationForScene { (s) -> TimeInterval? in -// return 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: 30, height: 30) -// t.iconForScene { (scene) -> UIImage? in -// return UIImage(named: "icon_download") -// } - - } - } - - } override var titles: [String] { @@ -52,6 +23,7 @@ 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) } else if indexPath.row == 1 { @@ -61,185 +33,5 @@ class ViewController: BaseListVC { } } - func testAlert() { - let a = Alert.push(scene: .loading) { (a) in - -// a.update() - } - a.update { (vm) in - vm.add(action: .default, title: "OK", 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() { - func f() { - Toast.push { (vm) in - vm.scene = .error - vm.title = "正在加载" - // vm.duration = 1 - vm.message = "请稍候片刻" - - }.didTapped { - debugPrint("didTapped") - }.didDisappear { - debugPrint("didDisappear") - } - } - - f() - - -// let t = Toast(scene: .loading, title: "正在加载", message: "请稍候片刻") - -// let a = Alert.push(scene : .loading, title: "正在加载", message: "请稍候片刻") -// a.didForceQuit { -// t.push() -// } -// -// t.didTapped { [weak t] in -// t?.pop() -// Alert.push(scene: .loading, title: "正在加载", message: "马上就要成功了") -// DispatchQueue.main.asyncAfter(deadline: .now()+1) { -// 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) -// } -// -// } -// } -// -// -// } -// -// } - - - - } - func testGuard() { - Guard.push { (vm) in - vm.add(title: "大标题") - vm.add(subTitle: "副标题") - vm.add(message: "请打开相机权限开关,否则无法进行测量。请打开相机权限开关,否则无法进行测量。") - vm.add(action: .default, title: "OK") { [weak vm] in - vm?.insert(action: 0, style: .destructive, title: "Del") { [weak vm] in - vm?.update(action: 0, style: .destructive, title: "Delete") { - vm?.remove(action: 0) - } - } - } - vm.insert(action: 0, style: .destructive, title: "Del") { [weak vm] in - - vm?.update(action: 0, style: .destructive, title: "Delete") { - vm?.remove(action: 0) - } - } - vm.add(action: .cancel, title: "Cancel") { - - } - - - } -// let g = ProHUD.Guard(title: "请求权限", message: "请打开相机权限开关,否则无法进行测量。") -// -// g.add(title: "呵呵") -// g.add(message: "请打开相机权限开关,否则无法进行测量。请打开相机权限开关,否则无法进行测量。") -// g.add(action: .default, title: "测试弹窗", handler: { [weak self] in -// self?.testToast() -// }) -// g.add(action: .destructive, title: "测试删除弹窗", handler: { [weak self] in -// self?.testDelete() -// }) -// g.add(action: .cancel, title: "我知道了", handler: nil) -// -// g.push(to: self) -// debugPrint("test: ", g) - } - - func testUpdateAction() { - 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() { - Guard.push(to: self) { (vm) in - vm.add(title: "测试") - vm.add(message: "测试测试") - vm.add(action: .default, title: "默认按钮", handler: { - - }) - vm.add(action: .cancel, title: "取消", handler: nil) - vm.vc?.view.backgroundColor = .clear - } - - - - } - - override func touchesBegan(_ touches: Set, with event: UIEvent?) { - - - - - } - } diff --git a/ProHUD/Alert/AlertController.swift b/ProHUD/Alert/AlertController.swift index 3d89da4..565fcd4 100644 --- a/ProHUD/Alert/AlertController.swift +++ b/ProHUD/Alert/AlertController.swift @@ -110,6 +110,7 @@ public extension Alert { /// 弹出屏幕 func pop() { + willDisappearCallback?() let window = Alert.privGetAlertWindow(self) Alert.privRemoveItemFromArray(alert: self) UIView.animateForAlertBuildOut(animations: { @@ -146,11 +147,6 @@ public extension Alert { vm.forceQuitCallback = callback } - /// 消失事件 - /// - Parameter callback: 事件回调 - func didDisappear(_ callback: (() -> Void)?) { - disappearCallback = callback - } func animate(rotate: Bool) { if rotate { diff --git a/ProHUD/Guard/GuardController.swift b/ProHUD/Guard/GuardController.swift index 9daf62b..a28242a 100644 --- a/ProHUD/Guard/GuardController.swift +++ b/ProHUD/Guard/GuardController.swift @@ -43,7 +43,7 @@ public extension ProHUD { }() /// 是否是强制性的(点击空白处是否可以消失) - public var force = false + public var isForce = false /// 是否是全屏的(仅手机竖屏有效) public var isFullScreen = false @@ -126,6 +126,7 @@ public extension Guard { func pop() { if displaying { debug("pop") + willDisappearCallback?() displaying = false view.isUserInteractionEnabled = false self.removeFromParent() @@ -146,14 +147,6 @@ public extension Guard { cfg.guard.reloadData(self) } - func willAppear(_ callback: (() -> Void)?) { - willAppearCallback = callback - } - /// 消失事件 - /// - Parameter callback: 事件回调 - func didDisappear(_ callback: (() -> Void)?) { - disappearCallback = callback - } } @@ -338,7 +331,7 @@ fileprivate extension Guard { @objc func privDidTapped(_ sender: UITapGestureRecognizer) { let point = sender.location(in: contentView) if point.x < 0 || point.y < 0 { - if force == false { + if isForce == false { // 点击到操作区域外部 pop() } diff --git a/ProHUD/HUDController.swift b/ProHUD/HUDController.swift index 327dda4..dbcfb98 100644 --- a/ProHUD/HUDController.swift +++ b/ProHUD/HUDController.swift @@ -10,10 +10,10 @@ import UIKit public class HUDController: UIViewController { - /// 消失回调 - internal var disappearCallback: (() -> Void)? - internal var willAppearCallback: (() -> Void)? + internal var didAppearCallback: (() -> Void)? + internal var willDisappearCallback: (() -> Void)? + internal var didDisappearCallback: (() -> Void)? /// 按钮事件 internal var buttonEvents = [UIButton:() -> Void]() @@ -42,10 +42,27 @@ public class HUDController: UIViewController { super.viewWillAppear(animated) willAppearCallback?() } - + public override func viewDidAppear(_ animated: Bool) { + super.viewDidAppear(animated) + didAppearCallback?() + } public override func viewDidDisappear(_ animated: Bool) { super.viewDidDisappear(animated) - disappearCallback?() + didDisappearCallback?() + } + + public func viewWillAppear(_ callback: (() -> Void)?) { + willAppearCallback = callback + } + public func viewDidAppear(_ callback: (() -> Void)?) { + didAppearCallback = callback + } + + public func viewWillDisappear(_ callback: (() -> Void)?) { + willDisappearCallback = callback + } + public func viewDidDisappear(_ callback: (() -> Void)?) { + didDisappearCallback = callback } } diff --git a/ProHUD/Toast/ToastController.swift b/ProHUD/Toast/ToastController.swift index 69bf920..0263ab2 100644 --- a/ProHUD/Toast/ToastController.swift +++ b/ProHUD/Toast/ToastController.swift @@ -169,16 +169,8 @@ public extension Toast { /// 点击事件 /// - Parameter callback: 事件回调 - @discardableResult func didTapped(_ callback: (() -> Void)?) -> Toast { + func didTapped(_ callback: (() -> Void)?) { vm.tapCallback = callback - return self - } - - /// 消失事件 - /// - Parameter callback: 事件回调 - @discardableResult func didDisappear(_ callback: (() -> Void)?) -> Toast { - disappearCallback = callback - return self } func animate(rotate: Bool) { @@ -225,6 +217,7 @@ public extension Toast { /// 弹出屏幕 /// - Parameter toast: 实例 class func pop(_ toast: Toast) { + toast.willDisappearCallback?() if toasts.count > 1 { for (i, t) in toasts.enumerated() { if t == toast { @@ -275,7 +268,7 @@ fileprivate extension Toast { window?.transform = .init(translationX: 0, y: point.y) if sender.state == .recognized { let v = sender.velocity(in: sender.view) - if vm.removable == true && (((window?.frame.origin.y ?? 0) < 0 && v.y < 0) || v.y < -1200) { + if vm.isRemovable == true && (((window?.frame.origin.y ?? 0) < 0 && v.y < 0) || v.y < -1200) { // 移除 self.pop() } else { diff --git a/ProHUD/Toast/ToastModel.swift b/ProHUD/Toast/ToastModel.swift index 639dd12..343841e 100644 --- a/ProHUD/Toast/ToastModel.swift +++ b/ProHUD/Toast/ToastModel.swift @@ -66,7 +66,7 @@ public extension Toast { public weak var vc: Toast? /// 是否可以通过手势移除(向上滑出屏幕) - public var removable = true + public var isRemovable = true // MARK: 私有