diff --git a/Example-Old/Example/AppDelegate.swift b/Example-Old/Example/AppDelegate.swift index 596d8f6..ad31f30 100644 --- a/Example-Old/Example/AppDelegate.swift +++ b/Example-Old/Example/AppDelegate.swift @@ -92,4 +92,32 @@ extension ProHUD.Scene { scene.message = "一旦购买拒不退款" return scene } + + /// 重写的loading场景 + static var loading: ProHUD.Scene { + var scene = ProHUD.Scene.init(identifier: "prohud.loading.rotate") + scene.image = UIImage(named: "prohud.rainbow.circle") + scene.title = "坐和放宽" + scene.message = "正在处理一些事情" + scene.alertDuration = 0 + scene.toastDuration = 0 + return scene + } + + static var sync: ProHUD.Scene { + var scene = ProHUD.Scene.init(identifier: "sync.rotate") + scene.image = UIImage(named: "prohud.rainbow.circle") + scene.title = "正在同步" + scene.alertDuration = 0 + scene.toastDuration = 0 + return scene + } + static var sync2: ProHUD.Scene { + var scene = ProHUD.Scene.init(identifier: "sync.rotate") + scene.image = UIImage(named: "prohud.rainbow.circle") + scene.alertDuration = 0 + scene.toastDuration = 0 + return scene + } + } diff --git a/Example-Old/Example/Assets.xcassets/Feel1.imageset/Contents.json b/Example-Old/Example/Assets.xcassets/Feel1.imageset/Contents.json new file mode 100644 index 0000000..b76d069 --- /dev/null +++ b/Example-Old/Example/Assets.xcassets/Feel1.imageset/Contents.json @@ -0,0 +1,22 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "Feel1@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "Feel1@3x.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Example-Old/Example/Assets.xcassets/Feel1.imageset/Feel1@2x.png b/Example-Old/Example/Assets.xcassets/Feel1.imageset/Feel1@2x.png new file mode 100644 index 0000000..1861f62 Binary files /dev/null and b/Example-Old/Example/Assets.xcassets/Feel1.imageset/Feel1@2x.png differ diff --git a/Example-Old/Example/Assets.xcassets/Feel1.imageset/Feel1@3x.png b/Example-Old/Example/Assets.xcassets/Feel1.imageset/Feel1@3x.png new file mode 100644 index 0000000..85e05f4 Binary files /dev/null and b/Example-Old/Example/Assets.xcassets/Feel1.imageset/Feel1@3x.png differ diff --git a/Example-Old/Example/BaseListVC.swift b/Example-Old/Example/BaseListVC.swift index d37958b..eeb1337 100644 --- a/Example-Old/Example/BaseListVC.swift +++ b/Example-Old/Example/BaseListVC.swift @@ -80,7 +80,7 @@ extension BaseListVC: UITableViewDataSource, UITableViewDelegate { cell.textLabel?.numberOfLines = 0 cell.detailTextLabel?.textColor = .gray cell.detailTextLabel?.numberOfLines = 0 - + cell.accessoryType = .disclosureIndicator } cell.textLabel?.text = vm.sections[indexPath.section].rows[indexPath.row].title cell.detailTextLabel?.text = vm.sections[indexPath.section].rows[indexPath.row].subtitle diff --git a/Example-Old/Example/TestAlertVC.swift b/Example-Old/Example/TestAlertVC.swift index ebd407b..e9de230 100644 --- a/Example-Old/Example/TestAlertVC.swift +++ b/Example-Old/Example/TestAlertVC.swift @@ -12,13 +12,28 @@ import ProHUD // 模拟2秒后同步成功 func loadingSuccessAfter2Seconds() { DispatchQueue.main.asyncAfter(deadline: .now()+2) { - Alert.find("loading", last: { (a) in + Alert.find("loading") { (a) in a.update { (vm) in vm.scene = .success vm.title = "同步成功" vm.message = nil } - }) + } + } +} + +func updateProgress(callback: @escaping (CGFloat) -> Void) { + let s = DispatchSemaphore(value: 1) + DispatchQueue.global().async { + for i in 0 ... 100 { + s.wait() + DispatchQueue.main.async { + callback(CGFloat(i)/100) + DispatchQueue.main.asyncAfter(deadline: .now()+0.03) { + s.signal() + } + } + } } } @@ -46,69 +61,43 @@ class TestAlertVC: BaseListVC { sec.footer = "这些是自带的场景,可以重写已有场景,或者扩展新的场景。" } - vm.addSection(title: "常用场景示例") { (sec) in - // MARK: 场景:同步成功(写法1) - sec.addRow(title: "场景:同步成功(写法1)") { - Alert.push("loading") { (a) in - a.update { (vm) in - vm.scene = .loading - vm.title = "正在同步" - vm.message = "请稍等片刻" - } - a.startRotate() - } + vm.addSection(title: "常用示例") { (sec) in + // MARK: 同步成功(写法1) + sec.addRow(title: "正在同步(写法1)", subtitle: "创建的时候就布局好了。") { + Alert.push("loading", scene: .sync) loadingSuccessAfter2Seconds() } - // MARK: 场景:同步成功(写法2) - sec.addRow(title: "场景:同步成功(写法2)") { - let a = Alert.push("loading") { (a) in - a.startRotate() - } - a.update { (vm) in - vm.scene = .loading - vm.title = "正在同步" - vm.message = "请稍等片刻" - } + // MARK: 同步成功(写法2) + sec.addRow(title: "正在同步(写法2)", subtitle: "创建的时候没有布局完,发出去之后再更新布局。") { + Alert.push("loading", scene: .sync2) loadingSuccessAfter2Seconds() - } - // MARK: 场景:正在同步(更新进度) - sec.addRow(title: "场景:正在同步(更新进度)") { - Alert.push("progress") { (a) in - a.update { (vm) in - vm.scene = .loading + // 先发出去再更新(添加文字) + Alert.find("loading") { (vc) in + vc.update { (vm) in vm.title = "正在同步" - vm.message = "请稍等片刻" } - a.startRotate() + } + } + // MARK: 正在同步(更新进度) + sec.addRow(title: "正在同步(有进度显示)") { + Alert.push("progress", scene: .sync) { (a) in a.update(progress: 0) - let s = DispatchSemaphore(value: 1) - DispatchQueue.global().async { - for i in 0 ... 100 { - s.wait() - DispatchQueue.main.async { - Alert.find("progress", last: { (a) in - a.update(progress: CGFloat(i)/100) - print("\(CGFloat(i)/100)") - if i == 100 { - DispatchQueue.main.asyncAfter(deadline: .now()+0.5) { - a.update { (vm) in - vm.scene = .success - vm.title = "同步成功" - vm.message = nil - } - } - } - }) - DispatchQueue.main.asyncAfter(deadline: .now()+0.03) { - s.signal() + updateProgress { (pct) in + a.update(progress: pct) + if pct >= 1 { + DispatchQueue.main.asyncAfter(deadline: .now()+0.5) { + a.update { (vm) in + vm.scene = .success + vm.title = "同步成功" + vm.message = nil } } } } } } - // MARK: 场景:同步失败和重试 - sec.addRow(title: "场景:同步失败和重试(布局变化)") { + // MARK: 同步失败和重试 + sec.addRow(title: "同步失败和重试(布局变化)", subtitle: "添加、删除按钮使得窗口大小发生了变化。") { Alert.push("loading", scene: .loading) func loading() { Alert.find("loading") { (a) in @@ -134,29 +123,45 @@ class TestAlertVC: BaseListVC { } loading() } - sec.footer = "两种写法1和写法2动画效果略微不同" + // MARK: 自定义要旋转的图片 + sec.addRow(title: "自定义要旋转的图片", subtitle: "添加了自定义视图,在更新的时候记得要视情况移除。") { + Alert.push(scene: .privacy, title: "正在授权") { (vc) in + vc.identifier = "loading" + let imgv = UIImageView(image: UIImage(named: "prohud.rainbow.circle")) + vc.imageView.addSubview(imgv) + imgv.tag = 1 + imgv.snp.makeConstraints { (mk) in + mk.center.equalToSuperview() + mk.width.height.equalTo(18) + } + vc.startRotate(imgv.layer, speed: 4) + vc.vm.duration = 0 + } + DispatchQueue.main.asyncAfter(deadline: .now() + 4) { + Alert.find("loading") { (vc) in + vc.imageView.viewWithTag(1)?.removeFromSuperview() + vc.update { (vm) in + vm.scene = .success + vm.title = "授权成功" + vm.duration = 1 + } + } + } + } + + sec.footer = "写法1和写法2动画效果略微不同" } vm.addSection(title: "为了解决代码逻辑疏漏导致程序卡死、弹窗重叠等问题") { (sec) in // MARK: 极端场景:正在同步(超时未处理) sec.addRow(title: "极端场景:正在同步(超时未处理)", subtitle: "超时未处理的意外情况,弹窗可以手动关闭。(在config中配置所需时间)") { - func f() { - Alert.push(scene: .loading, title: "正在同步", message: "请稍等片刻") { (a) in - a.identifier = "loading" - a.startRotate() - a.didForceQuit { - let t = Toast.push(scene: .loading, title: "正在同步", message: "请稍等片刻(点击展开为Alert)") { (vm) in - vm.identifier = "loading" - } - t.startRotate() - t.didTapped { [weak t] in - t?.pop() - f() - } - } + Alert.push(scene: .loading, title: "坐和放宽", message: "我们正在帮你搞定一切") { (a) in + a.identifier = "loading" + a.startRotate() + a.didForceQuit { + Toast.push(scene: .default, title: "点击了强制关闭", message: "您可以处理超时事件") } } - f() } @@ -188,29 +193,91 @@ class TestAlertVC: BaseListVC { DispatchQueue.main.asyncAfter(deadline: .now()+4) { loading(6) } - } - // MARK: 极端场景:多个不同的弹窗重叠 - sec.addRow(title: "极端场景:多个不同的弹窗重叠", subtitle: "多个弹窗不得不重叠的时候,ProHUD的景深处理可以使其看起来舒服一些。") { - func f(_ i: Int) { - Alert.push() { (a) in - a.startRotate() + DispatchQueue.main.asyncAfter(deadline: .now()+4.5) { + Alert.push("loading", scene: .success) { (a) in a.update { (vm) in - vm.scene = .loading - vm.title = "正在同步" + String(i) - vm.message = "请稍等片刻" + vm.scene = .success + vm.title = "测试结束" } } } - f(1) - DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) { - f(2) + } + // MARK: 极端场景:多个不同的弹窗重叠 + sec.addRow(title: "极端场景:多个不同的弹窗重叠", subtitle: "多个弹窗不得不重叠的时候,ProHUD的景深处理可以使其看起来舒服一些。") { + func a() { + Alert.push("a", scene: .default) { (a) in + a.update { (vm) in + vm.title = "Windows 10" + vm.message = "Windows 10不是為所有人設計,而是為每個人設計" + vm.icon = UIImage(named: "prohud.windmill") + vm.duration = 0 + } + DispatchQueue.main.asyncAfter(deadline: .now()+1) { + b() + } + } } - DispatchQueue.main.asyncAfter(deadline: .now() + 1) { - f(3) + func b() { + Alert.push("b", scene: .warning) { (a) in + a.update { (vm) in + vm.title = "Windows 10" + vm.message = "不要说我们没有警告过你" + vm.duration = 0 + } + } + DispatchQueue.main.asyncAfter(deadline: .now()+1) { + c() + } } - DispatchQueue.main.asyncAfter(deadline: .now() + 2) { - f(4) + func c() { + Alert.push("c", scene: .message) { (a) in + a.update { (vm) in + vm.title = "Windows 10" + vm.message = "我们都有不顺利的时候" + vm.duration = 0 + } + } + DispatchQueue.main.asyncAfter(deadline: .now()+1) { + d() + } } + func d() { + Alert.push("d", scene: .loading) { (a) in + a.update { (vm) in + vm.title = "Windows 10" + vm.message = "正在处理一些事情" + vm.duration = 0 + } + } + DispatchQueue.main.asyncAfter(deadline: .now()+3) { + e() + } + } + func e() { + Alert.push("e", scene: .failure) { (a) in + a.update { (vm) in + vm.title = "更新失败" + vm.message = "*回到以前的版本" + vm.add(action: .default, title: "好的") { + Alert.pop("e") + DispatchQueue.main.asyncAfter(deadline: .now()+0.3) { + Alert.pop("d") + } + DispatchQueue.main.asyncAfter(deadline: .now()+0.6) { + Alert.pop("c") + } + DispatchQueue.main.asyncAfter(deadline: .now()+0.9) { + Alert.pop("b") + } + DispatchQueue.main.asyncAfter(deadline: .now()+1.2) { + Alert.pop("a") + } + } + } + } + } + a() + } @@ -236,37 +303,26 @@ class TestAlertVC: BaseListVC { a.update { (vm) in vm.scene = .warning vm.title = "正在同步看到了你撒地方快乐撒的肌肤轮廓啊就是;来的跨省的人格人格离开那地方离开过正在同步看到了你撒地方快乐撒的肌肤轮廓啊就是;来的跨省的人格人格离开那地方离开过正在同步看到了你撒地方快乐撒的肌肤轮廓啊就是;来的跨省的人格人格离开那地方离开过" - vm.message = "正在同步看到了你撒地方快乐撒的肌肤轮廓啊就是;来的跨省的人格人格离开那地方离开过正在同步看到了你撒地方快乐撒的肌肤轮廓啊就是;来的跨省的人格人格离开那地方离开过正在同步看到了你撒地方快乐撒的肌肤轮廓啊就是;来的跨省的人格人格离开那地方离开过正在同步看到了你撒地方快乐撒的肌肤轮廓啊就是;来的跨省的人格人格离开那地方离开过正在同步看到了你撒地方快乐撒的肌肤轮廓啊就是;来的跨省的人格人格离开那地方离开过正在同步看到了你撒地方快乐撒的肌肤轮廓啊就是;来的跨省的人格人格离开那地方离开过" + vm.message = "正在同步看到了你撒地方快乐撒的肌肤轮廓啊就是;来的跨省的人格人格离开那地方离开过正在同步看到了你撒地方快乐撒的肌肤轮廓啊就是;来 的跨省的人格人格离开那地方离开过正在同步看到了你撒地方快乐撒的肌肤轮廓啊就是;来的跨省的人格人格离开那地方离开过正在同步看到了你撒地方快乐撒的肌肤轮廓啊就是;来的跨省的人格人格离开那地方离开过正在同步看到了你撒地方快乐撒的肌肤轮廓啊就是;来的跨省的人格人格离开那地方离开过正在同步看到了你撒地方快乐撒的肌肤轮廓啊就是;来的跨省的人格人格离开那地方离开过" vm.add(action: .default, title: "我知道了", handler: nil) } } } // MARK: 只有标题 sec.addRow(title: "只有标题") { - Alert.push(scene: .default, title: "标题") + Alert.push(scene: .message, title: "这是标题") } // MARK: 只有消息 sec.addRow(title: "只有消息") { - Alert.push(scene: .default, message: "这是消息") + Alert.push(scene: .message, message: "这是消息") } // MARK: 只有消息 sec.addRow(title: "既没有标题也没有消息") { - Alert.push("a") + Alert.push() } } } - func simulateSync() { - DispatchQueue.main.asyncAfter(deadline: .now() + 15) { - Alert.find("loading", last: { (a) in - a.update { (vm) in - vm.scene = .success - vm.title = "同步成功" - vm.message = "啊哈哈哈哈哈哈哈哈" - } - }) - } - } } diff --git a/Example-Old/Example/TestGuardVC.swift b/Example-Old/Example/TestGuardVC.swift index 3045518..bd32608 100644 --- a/Example-Old/Example/TestGuardVC.swift +++ b/Example-Old/Example/TestGuardVC.swift @@ -15,7 +15,7 @@ class TestGuardVC: BaseListVC { override func viewDidLoad() { super.viewDidLoad() - vm.addSection(title: "") { (sec) in + vm.addSection(title: "简单使用") { (sec) in // MARK: 场景:删除菜单 sec.addRow(title: "场景:删除菜单") { Guard.push("del") { (vc) in @@ -81,8 +81,49 @@ class TestGuardVC: BaseListVC { } } + } + + vm.addSection(title: "添加自定义视图") { (sec) in + // MARK: 场景:选项切换 + sec.addRow(title: "场景:选项切换", subtitle: "很方便地添加自定义控件") { + Guard.push() { (vc) in + + if #available(iOS 13.0, *) { + let imgv = UIImageView(image: UIImage(systemName: "photo.fill.on.rectangle.fill")) + vc.textStack.addArrangedSubview(imgv) + imgv.contentMode = .scaleAspectFit + imgv.snp.makeConstraints { (mk) in + mk.height.equalTo(80) + } + } else { + // Fallback on earlier versions + } + + vc.vm.add(title: "背景蒙版") + vc.vm.add(subTitle: "选择一种模糊效果") + let seg = UISegmentedControl(items: ["extraLight", "light", "dark", "none"]) + seg.selectedSegmentIndex = 1 + vc.textStack.addArrangedSubview(seg) + seg.snp.makeConstraints { (mk) in + mk.height.equalTo(40) + } + vc.vm.add(subTitle: "设置蒙版透明度") + let slider = UISlider() + slider.minimumValue = 0 + slider.maximumValue = 100 + slider.value = 100 + vc.textStack.addArrangedSubview(slider) + slider.snp.makeConstraints { (mk) in + mk.height.equalTo(40) + } + vc.vm.add(action: .default, title: "OK") { [weak vc] in + vc?.pop() + } + } + } + // MARK: 场景:隐私协议页面 - sec.addRow(title: "场景:隐私协议页面") { + sec.addRow(title: "场景:隐私协议页面", subtitle: "也可以完全控制整个页面") { Guard.push("license") { (vc) in vc.isFullScreen = true vc.update { (vm) in @@ -103,7 +144,9 @@ class TestGuardVC: BaseListVC { } } } - + } + + vm.addSection(title: "对比效果") { (sec) in // MARK: 对比:原生的ActionSheet sec.addRow(title: "对比:原生的ActionSheet") { let ac = UIAlertController(title: "Title", message: "message", preferredStyle: .actionSheet) @@ -122,8 +165,6 @@ class TestGuardVC: BaseListVC { self.present(vc, animated: true, completion: nil) } } - - } diff --git a/Example-Old/Example/TestToastVC.swift b/Example-Old/Example/TestToastVC.swift index a8705ab..6ff4688 100644 --- a/Example-Old/Example/TestToastVC.swift +++ b/Example-Old/Example/TestToastVC.swift @@ -9,7 +9,20 @@ import UIKit import ProHUD -typealias Callback2 = (String) -> Void +// 模拟15秒后同步成功 +func loadingSuccessAfter15Seconds() { + DispatchQueue.main.asyncAfter(deadline: .now() + 15) { + Toast.find("loading") { (a) in + a.update { (vm) in + vm.scene = .success + vm.title = "同步成功" + vm.message = "啊哈哈哈哈哈哈哈哈" + } + } + } +} + + class TestToastVC: BaseListVC { override func viewDidLoad() { @@ -17,43 +30,31 @@ class TestToastVC: BaseListVC { // Do any additional setup after loading the view. - vm.addSection(title: "基本场景") { (sec) in - // MARK: 场景:正在同步 - sec.addRow(title: "场景:正在同步") { - Toast.push(scene: .loading, title: "正在同步", message: "请稍等片刻") { (vm) in - vm.identifier = "loading" - }.startRotate() - self.simulateSync() + vm.addSection(title: "简单的例子") { (sec) in + // MARK: 场景:正在加载(没有进度显示) + sec.addRow(title: "场景:正在加载(没有进度显示)") { + Toast.push(scene: .loading).startRotate() + loadingSuccessAfter15Seconds() } - // MARK: 场景:正在同步(更新进度) - sec.addRow(title: "场景:正在同步(更新进度)") { + // MARK: 场景:正在加载(有进度显示) + sec.addRow(title: "场景:正在加载(有进度显示)") { if Toast.find("progress").count == 0 { - Toast.push("progress") { (t) in + Toast.push("progress", scene: .loading) { (t) in t.update { (vm) in - vm.scene = .loading - vm.title = "正在同步" - vm.message = "请稍等片刻" + vm.title = "笑容正在加载" + vm.message = "这通常不会太久" } t.startRotate() t.update(progress: 0) - let s = DispatchSemaphore(value: 1) - DispatchQueue.global().async { - for i in 0 ... 5 { - s.wait() - DispatchQueue.main.async { - Toast.find("progress", last: { (t) in - t.update(progress: CGFloat(i)/5) - print("\(CGFloat(i)/5)") - if i == 5 { - t.update { (vm) in - vm.scene = .success - vm.title = "同步成功" - vm.message = "xxx" - } - } - }) - DispatchQueue.main.asyncAfter(deadline: .now()+1) { - s.signal() + updateProgress { (pct) in + t.update(progress: pct) + if pct >= 1 { + DispatchQueue.main.asyncAfter(deadline: .now()+0.5) { + t.update { (vm) in + vm.scene = .success + vm.icon = UIImage(named: "Feel1") + vm.title = "加载成功" + vm.message = "阿哈哈哈哈.jpg" } } } @@ -82,7 +83,40 @@ class TestToastVC: BaseListVC { } } // MARK: 场景:设备电量过低 - sec.addRow(title: "场景:设备电量过低") { + sec.addRow(title: "场景:设备电量过低", subtitle: "这条消息正文部分显示多行") { + Toast.push(scene: .warning, title: "设备电量过低", message: "请及时对设备进行充电,以免影响使用。\n为了您的续航,我们已经为您限制了设备的峰值性能。") { (vc) in + vc.vm.duration = 0 + } + } + } + + vm.addSection(title: "实用的例子") { (sec) in + // MARK: 避免重复发布同一条信息 + sec.addRow(title: "避免重复发布同一条信息 (id=aaa)", subtitle: "为一个实例指定 identifier 可以避免重复出现。") { + Toast.push("aaa") { (vc) in + vc.update { (vm) in + vm.scene = .warning + vm.message = "这则消息不会同时出现在多条横幅中。" + vm.duration = 0 + } + vc.pulse() + } + } + // MARK: 根据 identifier 查找并修改实例 + sec.addRow(title: "根据 identifier 查找并修改实例 (id=aaa)", subtitle: "在本例中,如果找不到就不进行处理。") { + // 本例和上例唯一的区别是 push -> find + Toast.find("aaa") { (t) in + t.update { (vm) in + vm.scene = .success + vm.title = "找到了哈哈" + vm.message = "根据 identifier 查找并修改实例" + vm.duration = 0 + } + t.pulse() + } + } + // MARK: 传入指定图标 + sec.addRow(title: "传入指定图标", subtitle: "虽然您对实例具有有完全的自由,但是更建议提前在场景中设置好对应的图片。") { Toast.push(scene: .default, title: "传入指定图标测试", message: "这是消息内容") { (vc) in vc.update { (vm) in if #available(iOS 13.0, *) { @@ -94,15 +128,8 @@ class TestToastVC: BaseListVC { } } } - } - - vm.addSection(title: "") { (sec) in - // MARK: 传入指定图标 - sec.addRow(title: "传入指定图标") { - Toast.push(scene: .warning, title: "设备电量过低", message: "请及时对设备进行充电,以免影响使用。") - } // MARK: 禁止手势移除 - sec.addRow(title: "禁止手势移除") { + sec.addRow(title: "禁止手势移除", subtitle: "常用于优先级低但是必须用户处理的事件。") { Toast.push(scene: .default, title: "禁止手势移除", message: "这条消息无法通过向上滑动移出屏幕。5秒后自动消失,每次拖拽都会刷新倒计时。") { (vc) in vc.isRemovable = false vc.update { (vm) in @@ -111,7 +138,7 @@ class TestToastVC: BaseListVC { } } // MARK: 组合使用示例 - sec.addRow(title: "组合使用示例") { + sec.addRow(title: "和弹窗组合使用示例", subtitle: "如果有一个横幅消息需要用户做出选择怎么办?可以点击的时候弹出一个弹窗来。") { Toast.push(scene: .message, title: "好友邀请", message: "你收到一条好友邀请,点击查看详情。", duration: 10) { (vc) in vc.identifier = "xxx" vc.didTapped { [weak vc] in @@ -130,34 +157,38 @@ class TestToastVC: BaseListVC { } } } - // MARK: 避免重复发布同一条信息 - sec.addRow(title: "避免重复发布同一条信息") { - if let t = Toast.find("aaa").last { - t.pulse() - t.update() { (vm) in - vm.title = "已经存在了" + + // MARK: 自定义要旋转的图片 + sec.addRow(title: "自定义要旋转的图片", subtitle: "添加了自定义视图,在更新的时候记得要视情况移除。") { + Toast.push(scene: .privacy, title: "正在授权", message: "请稍等片刻") { (t) in + t.identifier = "loading" + let imgv = UIImageView(image: UIImage(named: "prohud.rainbow.circle")) + t.imageView.addSubview(imgv) + imgv.tag = 1 + imgv.snp.makeConstraints { (mk) in + mk.center.equalToSuperview() + mk.width.height.equalTo(18) } - } else { - Toast.push(title: "这是一条id为aaa的横幅", message: "避免重复发布同一条信息") { (t) in - t.identifier = "aaa" - t.update { (vm) in - vm.scene = .warning - vm.duration = 0 + t.startRotate(imgv.layer, speed: 4) + t.vm.duration = 0 + } + DispatchQueue.main.asyncAfter(deadline: .now() + 5) { + Toast.find("loading") { (a) in + a.imageView.viewWithTag(1)?.removeFromSuperview() + a.update { (vm) in + vm.scene = .success + vm.title = "授权成功" + vm.message = "啊哈哈哈哈哈哈哈哈" } } } } - // MARK: 根据id查找并修改实例 - sec.addRow(title: "根据id查找并修改实例") { - Toast.push("aaa") { (t) in - t.update { (vm) in - vm.scene = .success - vm.title = "找到了哈哈" - vm.message = "根据id查找并修改实例" - } - t.pulse() - } - } + + } + + + vm.addSection(title: "极端场景") { (sec) in + // MARK: 测试较长的标题和内容 sec.addRow(title: "测试较长的标题和内容") { Toast.push() { (a) in @@ -169,7 +200,7 @@ class TestToastVC: BaseListVC { } } // MARK: 测试特别长的标题和内容 - sec.addRow(title: "测试特别长的标题和内容") { + sec.addRow(title: "测试特别长的标题和内容", subtitle: "可以在配置中设置 titleMaxLines/bodyMaxLines 来避免出现这种情况。") { Toast.push() { (a) in a.update { (vm) in vm.title = "正在同步看到了你撒地方快乐撒的肌肤轮廓啊就是;来的跨省的人格人格离开那地方离开过正在同步看到了你撒地方快乐撒的肌肤轮廓啊就是;来的跨省的人格人格离开那地方离开过正在同步看到了你撒地方快乐撒的肌肤轮廓啊就是;来的跨省的人格人格离开那地方离开过" @@ -178,55 +209,27 @@ class TestToastVC: BaseListVC { } } } - // MARK: 测试只有title - sec.addRow(title: "测试只有title") { + // MARK: 只有标题 + sec.addRow(title: "只有标题部分的效果", subtitle: "这种情况请控制文字不要太少,否则不美观。") { Toast.push() { (a) in a.update { (vm) in - vm.scene = .warning - vm.title = "正在同步看到了你撒地" - + vm.title = "坐和放宽,我们正在帮你搞定一切,这通常不会太久。" } } } - // MARK: 测试只有message - sec.addRow(title: "测试只有message") { + // MARK: 只有正文 + sec.addRow(title: "只有正文部分的效果", subtitle: "这种情况请控制文字不要太少,否则不美观。") { Toast.push() { (a) in a.update { (vm) in - vm.scene = .warning - vm.message = "正在同步看到了你撒地方快乐撒的肌肤轮廓啊就是;来的跨省的人格人格离开那地方离开过正在同步看到了你撒地方快乐撒的肌肤轮廓啊就是;来的跨省的人格人格离开那地方离开过正在同步看到了你撒地方快乐撒的肌肤轮廓啊就是;来的跨省的人格人格离开那地方离开过正在同步看到了你撒地方快乐撒的肌肤轮廓啊就是;来的跨省的人格人格离开那地方离开过正在同步看到了你撒地方快乐撒的肌肤轮廓啊就是;来的跨省的人格人格离开那地方离开过正在同步看到了你撒地方快乐撒的肌肤轮廓啊就是;来的跨省的人格人格离开那地方离开过" - + vm.message = "坐和放宽,我们正在帮你搞定一切,这通常不会太久。\n不幸的是,它花费的时间比通常要长。" } } } - // MARK: 自定义旋转的图片 - sec.addRow(title: "自定义旋转的图片") { - Toast.push(scene: .privacy, title: "正在授权", message: "请稍等片刻") { (t) in - t.identifier = "loading" - let imgv = UIImageView(image: UIImage(named: "prohud.rainbow.circle")) - t.imageView.addSubview(imgv) - imgv.snp.makeConstraints { (mk) in - mk.center.equalToSuperview() - mk.width.height.equalTo(18) - } - t.startRotate(imgv.layer, speed: 4) - } - self.simulateSync() - } + + } - } - - - func simulateSync() { - DispatchQueue.main.asyncAfter(deadline: .now() + 15) { - Toast.find("loading", last: { (a) in - a.update { (vm) in - vm.scene = .success - vm.title = "同步成功" - vm.message = "啊哈哈哈哈哈哈哈哈" - } - }) - } + } } diff --git a/Example-Old/Example/ViewController.swift b/Example-Old/Example/ViewController.swift index 3448d54..580b30c 100644 --- a/Example-Old/Example/ViewController.swift +++ b/Example-Old/Example/ViewController.swift @@ -7,7 +7,7 @@ // import UIKit -//import ProHUD +import ProHUD import SnapKit class ViewController: BaseListVC { @@ -17,22 +17,39 @@ class ViewController: BaseListVC { // Do any additional setup after loading the view. title = "\(Bundle.main.infoDictionary?["CFBundleName"] ?? "ProHUD")" - vm.addSection(title: "") { (sec) in - sec.addRow(title: "Toast") { + vm.addSection(title: "测试项目") { (sec) in + sec.addRow(title: "Toast", subtitle: "横幅控件,支持图片、标题和正文。\n不支持添加按钮,但可以接受一个点击事件。") { let vc = TestToastVC() vc.title = "Toast" self.navigationController?.pushViewController(vc, animated: true) } - sec.addRow(title: "Alert") { + sec.addRow(title: "Alert", subtitle: "弹窗控件,支持图片、标题、正文和按钮。\n按钮不设置事件回调时可以自动pop。") { let vc = TestAlertVC() vc.title = "Alert" self.navigationController?.pushViewController(vc, animated: true) } - sec.addRow(title: "Guard") { + sec.addRow(title: "Guard", subtitle: "操作表控件,原生支持标题、副标题、正文和按钮,也可以添加任意视图。") { let vc = TestGuardVC() vc.title = "Guard" self.navigationController?.pushViewController(vc, animated: true) } + + } + + + vm.addSection(title: "小提示") { (sec) in + sec.addRow(title: "所有控件都是ViewController", subtitle: "可以监听进入、离开移除事件。\n推入、推出统一为 push/pop 操作。\n所有控件都可以在配置中完全自定义布局及样式。\n通过 identifier 来获取实例,方便进行多实例管理") { + } + sec.addRow(title: "基于场景的应用", subtitle: "一个场景就是一套模板,原生提供了一些常用场景,您可以覆写,也可以新建场景。\n在场景中可以指定持续时间、标题、图标、正文等数据。") { + } + sec.addRow(title: "样式与逻辑分离", subtitle: "您可以在场景中指定一些规则,也可以在配置中完全自定义布局样式。\n在使用的时候呢,只需要确定数据即可。") { + } + sec.addRow(title: "Loading图片旋转", subtitle: "可以通过调用 .startRotate() 并可传入适当参数来旋转,也可以自定义场景\n如果场景的 identifier 包含 .rotate 则会自动旋转图片") { + } + sec.addRow(title: "按钮默认行为", subtitle: "为了灵活性,default 和 destructive 按钮默认不会对实例进行 pop 操作,但是如果它们没有实现回调事件,则会自动 pop。cancel 按钮永远会自动 pop。") { + } + sec.addRow(title: "持续时间", subtitle: "设置 duration 来指定持续时间,设置为 0 可以永久持续。\n原生提供的 loading 场景持续时间为永久。\n如果弹窗添加了按钮,则持续时间会自动变成永久,除非手动设置。") { + } } } diff --git a/Source/ProHUD.swift b/Source/ProHUD.swift index 5c3b35d..534e8d9 100644 --- a/Source/ProHUD.swift +++ b/Source/ProHUD.swift @@ -47,6 +47,8 @@ public extension ProHUD.Scene { static var message: ProHUD.Scene { var scene = ProHUD.Scene.init(identifier: "prohud.message") scene.image = ProHUD.image(named: "prohud.message") + scene.alertDuration = 2 + scene.toastDuration = 5 return scene } static var loading: ProHUD.Scene {