This commit is contained in:
xaoxuu 2020-06-24 13:27:50 +08:00
parent 76fdad3289
commit 84b9931a8a
10 changed files with 383 additions and 214 deletions

View File

@ -92,4 +92,32 @@ extension ProHUD.Scene {
scene.message = "一旦购买拒不退款" scene.message = "一旦购买拒不退款"
return scene 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
}
} }

View File

@ -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
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.7 KiB

View File

@ -80,7 +80,7 @@ extension BaseListVC: UITableViewDataSource, UITableViewDelegate {
cell.textLabel?.numberOfLines = 0 cell.textLabel?.numberOfLines = 0
cell.detailTextLabel?.textColor = .gray cell.detailTextLabel?.textColor = .gray
cell.detailTextLabel?.numberOfLines = 0 cell.detailTextLabel?.numberOfLines = 0
cell.accessoryType = .disclosureIndicator
} }
cell.textLabel?.text = vm.sections[indexPath.section].rows[indexPath.row].title cell.textLabel?.text = vm.sections[indexPath.section].rows[indexPath.row].title
cell.detailTextLabel?.text = vm.sections[indexPath.section].rows[indexPath.row].subtitle cell.detailTextLabel?.text = vm.sections[indexPath.section].rows[indexPath.row].subtitle

View File

@ -12,13 +12,28 @@ import ProHUD
// 2 // 2
func loadingSuccessAfter2Seconds() { func loadingSuccessAfter2Seconds() {
DispatchQueue.main.asyncAfter(deadline: .now()+2) { DispatchQueue.main.asyncAfter(deadline: .now()+2) {
Alert.find("loading", last: { (a) in Alert.find("loading") { (a) in
a.update { (vm) in a.update { (vm) in
vm.scene = .success vm.scene = .success
vm.title = "同步成功" vm.title = "同步成功"
vm.message = nil 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,50 +61,30 @@ class TestAlertVC: BaseListVC {
sec.footer = "这些是自带的场景,可以重写已有场景,或者扩展新的场景。" sec.footer = "这些是自带的场景,可以重写已有场景,或者扩展新的场景。"
} }
vm.addSection(title: "常用场景示例") { (sec) in vm.addSection(title: "常用示例") { (sec) in
// MARK: 1 // MARK: 1
sec.addRow(title: "场景同步成功写法1") { sec.addRow(title: "正在同步写法1", subtitle: "创建的时候就布局好了。") {
Alert.push("loading") { (a) in Alert.push("loading", scene: .sync)
a.update { (vm) in
vm.scene = .loading
vm.title = "正在同步"
vm.message = "请稍等片刻"
}
a.startRotate()
}
loadingSuccessAfter2Seconds() loadingSuccessAfter2Seconds()
} }
// MARK: 2 // MARK: 2
sec.addRow(title: "场景同步成功写法2") { sec.addRow(title: "正在同步写法2", subtitle: "创建的时候没有布局完,发出去之后再更新布局。") {
let a = Alert.push("loading") { (a) in Alert.push("loading", scene: .sync2)
a.startRotate()
}
a.update { (vm) in
vm.scene = .loading
vm.title = "正在同步"
vm.message = "请稍等片刻"
}
loadingSuccessAfter2Seconds() loadingSuccessAfter2Seconds()
} //
// MARK: Alert.find("loading") { (vc) in
sec.addRow(title: "场景:正在同步(更新进度)") { vc.update { (vm) in
Alert.push("progress") { (a) in
a.update { (vm) in
vm.scene = .loading
vm.title = "正在同步" vm.title = "正在同步"
vm.message = "请稍等片刻"
} }
a.startRotate() }
}
// MARK:
sec.addRow(title: "正在同步(有进度显示)") {
Alert.push("progress", scene: .sync) { (a) in
a.update(progress: 0) a.update(progress: 0)
let s = DispatchSemaphore(value: 1) updateProgress { (pct) in
DispatchQueue.global().async { a.update(progress: pct)
for i in 0 ... 100 { if pct >= 1 {
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) { DispatchQueue.main.asyncAfter(deadline: .now()+0.5) {
a.update { (vm) in a.update { (vm) in
vm.scene = .success vm.scene = .success
@ -98,17 +93,11 @@ class TestAlertVC: BaseListVC {
} }
} }
} }
})
DispatchQueue.main.asyncAfter(deadline: .now()+0.03) {
s.signal()
} }
} }
} }
} // MARK:
} sec.addRow(title: "同步失败和重试(布局变化)", subtitle: "添加、删除按钮使得窗口大小发生了变化。") {
}
// MARK:
sec.addRow(title: "场景:同步失败和重试(布局变化)") {
Alert.push("loading", scene: .loading) Alert.push("loading", scene: .loading)
func loading() { func loading() {
Alert.find("loading") { (a) in Alert.find("loading") { (a) in
@ -134,30 +123,46 @@ class TestAlertVC: BaseListVC {
} }
loading() 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 vm.addSection(title: "为了解决代码逻辑疏漏导致程序卡死、弹窗重叠等问题") { (sec) in
// MARK: // MARK:
sec.addRow(title: "极端场景:正在同步(超时未处理)", subtitle: "超时未处理的意外情况弹窗可以手动关闭。在config中配置所需时间") { sec.addRow(title: "极端场景:正在同步(超时未处理)", subtitle: "超时未处理的意外情况弹窗可以手动关闭。在config中配置所需时间") {
func f() { Alert.push(scene: .loading, title: "坐和放宽", message: "我们正在帮你搞定一切") { (a) in
Alert.push(scene: .loading, title: "正在同步", message: "请稍等片刻") { (a) in
a.identifier = "loading" a.identifier = "loading"
a.startRotate() a.startRotate()
a.didForceQuit { a.didForceQuit {
let t = Toast.push(scene: .loading, title: "正在同步", message: "请稍等片刻点击展开为Alert") { (vm) in Toast.push(scene: .default, title: "点击了强制关闭", message: "您可以处理超时事件")
vm.identifier = "loading"
}
t.startRotate()
t.didTapped { [weak t] in
t?.pop()
f()
} }
} }
} }
}
f()
}
// MARK: // MARK:
@ -188,30 +193,92 @@ class TestAlertVC: BaseListVC {
DispatchQueue.main.asyncAfter(deadline: .now()+4) { DispatchQueue.main.asyncAfter(deadline: .now()+4) {
loading(6) loading(6)
} }
DispatchQueue.main.asyncAfter(deadline: .now()+4.5) {
Alert.push("loading", scene: .success) { (a) in
a.update { (vm) in
vm.scene = .success
vm.title = "测试结束"
}
}
}
} }
// MARK: // MARK:
sec.addRow(title: "极端场景:多个不同的弹窗重叠", subtitle: "多个弹窗不得不重叠的时候ProHUD的景深处理可以使其看起来舒服一些。") { sec.addRow(title: "极端场景:多个不同的弹窗重叠", subtitle: "多个弹窗不得不重叠的时候ProHUD的景深处理可以使其看起来舒服一些。") {
func f(_ i: Int) { func a() {
Alert.push() { (a) in Alert.push("a", scene: .default) { (a) in
a.startRotate()
a.update { (vm) in a.update { (vm) in
vm.scene = .loading vm.title = "Windows 10"
vm.title = "正在同步" + String(i) vm.message = "Windows 10不是為所有人設計,而是為每個人設計"
vm.message = "请稍等片刻" vm.icon = UIImage(named: "prohud.windmill")
vm.duration = 0
}
DispatchQueue.main.asyncAfter(deadline: .now()+1) {
b()
} }
} }
} }
f(1) func b() {
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) { Alert.push("b", scene: .warning) { (a) in
f(2) a.update { (vm) in
vm.title = "Windows 10"
vm.message = "不要说我们没有警告过你"
vm.duration = 0
} }
DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
f(3)
} }
DispatchQueue.main.asyncAfter(deadline: .now() + 2) { DispatchQueue.main.asyncAfter(deadline: .now()+1) {
f(4) c()
} }
} }
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 a.update { (vm) in
vm.scene = .warning vm.scene = .warning
vm.title = "正在同步看到了你撒地方快乐撒的肌肤轮廓啊就是;来的跨省的人格人格离开那地方离开过正在同步看到了你撒地方快乐撒的肌肤轮廓啊就是;来的跨省的人格人格离开那地方离开过正在同步看到了你撒地方快乐撒的肌肤轮廓啊就是;来的跨省的人格人格离开那地方离开过" vm.title = "正在同步看到了你撒地方快乐撒的肌肤轮廓啊就是;来的跨省的人格人格离开那地方离开过正在同步看到了你撒地方快乐撒的肌肤轮廓啊就是;来的跨省的人格人格离开那地方离开过正在同步看到了你撒地方快乐撒的肌肤轮廓啊就是;来的跨省的人格人格离开那地方离开过"
vm.message = "正在同步看到了你撒地方快乐撒的肌肤轮廓啊就是;来的跨省的人格人格离开那地方离开过正在同步看到了你撒地方快乐撒的肌肤轮廓啊就是;来的跨省的人格人格离开那地方离开过正在同步看到了你撒地方快乐撒的肌肤轮廓啊就是;来的跨省的人格人格离开那地方离开过正在同步看到了你撒地方快乐撒的肌肤轮廓啊就是;来的跨省的人格人格离开那地方离开过正在同步看到了你撒地方快乐撒的肌肤轮廓啊就是;来的跨省的人格人格离开那地方离开过正在同步看到了你撒地方快乐撒的肌肤轮廓啊就是;来的跨省的人格人格离开那地方离开过" vm.message = "正在同步看到了你撒地方快乐撒的肌肤轮廓啊就是;来的跨省的人格人格离开那地方离开过正在同步看到了你撒地方快乐撒的肌肤轮廓啊就是;来 的跨省的人格人格离开那地方离开过正在同步看到了你撒地方快乐撒的肌肤轮廓啊就是;来的跨省的人格人格离开那地方离开过正在同步看到了你撒地方快乐撒的肌肤轮廓啊就是;来的跨省的人格人格离开那地方离开过正在同步看到了你撒地方快乐撒的肌肤轮廓啊就是;来的跨省的人格人格离开那地方离开过正在同步看到了你撒地方快乐撒的肌肤轮廓啊就是;来的跨省的人格人格离开那地方离开过"
vm.add(action: .default, title: "我知道了", handler: nil) vm.add(action: .default, title: "我知道了", handler: nil)
} }
} }
} }
// MARK: // MARK:
sec.addRow(title: "只有标题") { sec.addRow(title: "只有标题") {
Alert.push(scene: .default, title: "标题") Alert.push(scene: .message, title: "这是标题")
} }
// MARK: // MARK:
sec.addRow(title: "只有消息") { sec.addRow(title: "只有消息") {
Alert.push(scene: .default, message: "这是消息") Alert.push(scene: .message, message: "这是消息")
} }
// MARK: // MARK:
sec.addRow(title: "既没有标题也没有消息") { 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 = "啊哈哈哈哈哈哈哈哈"
}
})
}
}
} }

View File

@ -15,7 +15,7 @@ class TestGuardVC: BaseListVC {
override func viewDidLoad() { override func viewDidLoad() {
super.viewDidLoad() super.viewDidLoad()
vm.addSection(title: "") { (sec) in vm.addSection(title: "简单使用") { (sec) in
// MARK: // MARK:
sec.addRow(title: "场景:删除菜单") { sec.addRow(title: "场景:删除菜单") {
Guard.push("del") { (vc) in 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: // MARK:
sec.addRow(title: "场景:隐私协议页面") { sec.addRow(title: "场景:隐私协议页面", subtitle: "也可以完全控制整个页面") {
Guard.push("license") { (vc) in Guard.push("license") { (vc) in
vc.isFullScreen = true vc.isFullScreen = true
vc.update { (vm) in vc.update { (vm) in
@ -103,7 +144,9 @@ class TestGuardVC: BaseListVC {
} }
} }
} }
}
vm.addSection(title: "对比效果") { (sec) in
// MARK: ActionSheet // MARK: ActionSheet
sec.addRow(title: "对比原生的ActionSheet") { sec.addRow(title: "对比原生的ActionSheet") {
let ac = UIAlertController(title: "Title", message: "message", preferredStyle: .actionSheet) let ac = UIAlertController(title: "Title", message: "message", preferredStyle: .actionSheet)
@ -122,8 +165,6 @@ class TestGuardVC: BaseListVC {
self.present(vc, animated: true, completion: nil) self.present(vc, animated: true, completion: nil)
} }
} }
} }

View File

@ -9,7 +9,20 @@
import UIKit import UIKit
import ProHUD 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 { class TestToastVC: BaseListVC {
override func viewDidLoad() { override func viewDidLoad() {
@ -17,43 +30,31 @@ class TestToastVC: BaseListVC {
// Do any additional setup after loading the view. // Do any additional setup after loading the view.
vm.addSection(title: "基本场景") { (sec) in vm.addSection(title: "简单的例子") { (sec) in
// MARK: // MARK:
sec.addRow(title: "场景:正在同步") { sec.addRow(title: "场景:正在加载(没有进度显示)") {
Toast.push(scene: .loading, title: "正在同步", message: "请稍等片刻") { (vm) in Toast.push(scene: .loading).startRotate()
vm.identifier = "loading" loadingSuccessAfter15Seconds()
}.startRotate()
self.simulateSync()
} }
// MARK: // MARK:
sec.addRow(title: "场景:正在同步(更新进度") { sec.addRow(title: "场景:正在加载(有进度显示") {
if Toast.find("progress").count == 0 { if Toast.find("progress").count == 0 {
Toast.push("progress") { (t) in Toast.push("progress", scene: .loading) { (t) in
t.update { (vm) in t.update { (vm) in
vm.scene = .loading vm.title = "笑容正在加载"
vm.title = "正在同步" vm.message = "这通常不会太久"
vm.message = "请稍等片刻"
} }
t.startRotate() t.startRotate()
t.update(progress: 0) t.update(progress: 0)
let s = DispatchSemaphore(value: 1) updateProgress { (pct) in
DispatchQueue.global().async { t.update(progress: pct)
for i in 0 ... 5 { if pct >= 1 {
s.wait() DispatchQueue.main.asyncAfter(deadline: .now()+0.5) {
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 t.update { (vm) in
vm.scene = .success vm.scene = .success
vm.title = "同步成功" vm.icon = UIImage(named: "Feel1")
vm.message = "xxx" vm.title = "加载成功"
} vm.message = "阿哈哈哈哈.jpg"
}
})
DispatchQueue.main.asyncAfter(deadline: .now()+1) {
s.signal()
} }
} }
} }
@ -82,7 +83,40 @@ class TestToastVC: BaseListVC {
} }
} }
// MARK: // 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 Toast.push(scene: .default, title: "传入指定图标测试", message: "这是消息内容") { (vc) in
vc.update { (vm) in vc.update { (vm) in
if #available(iOS 13.0, *) { 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: // MARK:
sec.addRow(title: "禁止手势移除") { sec.addRow(title: "禁止手势移除", subtitle: "常用于优先级低但是必须用户处理的事件。") {
Toast.push(scene: .default, title: "禁止手势移除", message: "这条消息无法通过向上滑动移出屏幕。5秒后自动消失每次拖拽都会刷新倒计时。") { (vc) in Toast.push(scene: .default, title: "禁止手势移除", message: "这条消息无法通过向上滑动移出屏幕。5秒后自动消失每次拖拽都会刷新倒计时。") { (vc) in
vc.isRemovable = false vc.isRemovable = false
vc.update { (vm) in vc.update { (vm) in
@ -111,7 +138,7 @@ class TestToastVC: BaseListVC {
} }
} }
// MARK: 使 // MARK: 使
sec.addRow(title: "组合使用示例") { sec.addRow(title: "和弹窗组合使用示例", subtitle: "如果有一个横幅消息需要用户做出选择怎么办?可以点击的时候弹出一个弹窗来。") {
Toast.push(scene: .message, title: "好友邀请", message: "你收到一条好友邀请,点击查看详情。", duration: 10) { (vc) in Toast.push(scene: .message, title: "好友邀请", message: "你收到一条好友邀请,点击查看详情。", duration: 10) { (vc) in
vc.identifier = "xxx" vc.identifier = "xxx"
vc.didTapped { [weak vc] in vc.didTapped { [weak vc] in
@ -130,34 +157,38 @@ class TestToastVC: BaseListVC {
} }
} }
} }
// MARK:
sec.addRow(title: "避免重复发布同一条信息") { // MARK:
if let t = Toast.find("aaa").last { sec.addRow(title: "自定义要旋转的图片", subtitle: "添加了自定义视图,在更新的时候记得要视情况移除。") {
t.pulse() Toast.push(scene: .privacy, title: "正在授权", message: "请稍等片刻") { (t) in
t.update() { (vm) in t.identifier = "loading"
vm.title = "已经存在了" 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 { t.startRotate(imgv.layer, speed: 4)
Toast.push(title: "这是一条id为aaa的横幅", message: "避免重复发布同一条信息") { (t) in t.vm.duration = 0
t.identifier = "aaa"
t.update { (vm) in
vm.scene = .warning
vm.duration = 0
} }
} DispatchQueue.main.asyncAfter(deadline: .now() + 5) {
} Toast.find("loading") { (a) in
} a.imageView.viewWithTag(1)?.removeFromSuperview()
// MARK: id a.update { (vm) in
sec.addRow(title: "根据id查找并修改实例") {
Toast.push("aaa") { (t) in
t.update { (vm) in
vm.scene = .success vm.scene = .success
vm.title = "找到了哈哈" vm.title = "授权成功"
vm.message = "根据id查找并修改实例" vm.message = "啊哈哈哈哈哈哈哈哈"
}
t.pulse()
} }
} }
}
}
}
vm.addSection(title: "极端场景") { (sec) in
// MARK: // MARK:
sec.addRow(title: "测试较长的标题和内容") { sec.addRow(title: "测试较长的标题和内容") {
Toast.push() { (a) in Toast.push() { (a) in
@ -169,7 +200,7 @@ class TestToastVC: BaseListVC {
} }
} }
// MARK: // MARK:
sec.addRow(title: "测试特别长的标题和内容") { sec.addRow(title: "测试特别长的标题和内容", subtitle: "可以在配置中设置 titleMaxLines/bodyMaxLines 来避免出现这种情况。") {
Toast.push() { (a) in Toast.push() { (a) in
a.update { (vm) in a.update { (vm) in
vm.title = "正在同步看到了你撒地方快乐撒的肌肤轮廓啊就是;来的跨省的人格人格离开那地方离开过正在同步看到了你撒地方快乐撒的肌肤轮廓啊就是;来的跨省的人格人格离开那地方离开过正在同步看到了你撒地方快乐撒的肌肤轮廓啊就是;来的跨省的人格人格离开那地方离开过" vm.title = "正在同步看到了你撒地方快乐撒的肌肤轮廓啊就是;来的跨省的人格人格离开那地方离开过正在同步看到了你撒地方快乐撒的肌肤轮廓啊就是;来的跨省的人格人格离开那地方离开过正在同步看到了你撒地方快乐撒的肌肤轮廓啊就是;来的跨省的人格人格离开那地方离开过"
@ -178,55 +209,27 @@ class TestToastVC: BaseListVC {
} }
} }
} }
// MARK: title // MARK:
sec.addRow(title: "测试只有title") { sec.addRow(title: "只有标题部分的效果", subtitle: "这种情况请控制文字不要太少,否则不美观。") {
Toast.push() { (a) in Toast.push() { (a) in
a.update { (vm) in a.update { (vm) in
vm.scene = .warning vm.title = "坐和放宽,我们正在帮你搞定一切,这通常不会太久。"
vm.title = "正在同步看到了你撒地"
} }
} }
} }
// MARK: message // MARK:
sec.addRow(title: "测试只有message") { sec.addRow(title: "只有正文部分的效果", subtitle: "这种情况请控制文字不要太少,否则不美观。") {
Toast.push() { (a) in Toast.push() { (a) in
a.update { (vm) in a.update { (vm) in
vm.scene = .warning vm.message = "坐和放宽,我们正在帮你搞定一切,这通常不会太久。\n不幸的是,它花费的时间比通常要长。"
vm.message = "正在同步看到了你撒地方快乐撒的肌肤轮廓啊就是;来的跨省的人格人格离开那地方离开过正在同步看到了你撒地方快乐撒的肌肤轮廓啊就是;来的跨省的人格人格离开那地方离开过正在同步看到了你撒地方快乐撒的肌肤轮廓啊就是;来的跨省的人格人格离开那地方离开过正在同步看到了你撒地方快乐撒的肌肤轮廓啊就是;来的跨省的人格人格离开那地方离开过正在同步看到了你撒地方快乐撒的肌肤轮廓啊就是;来的跨省的人格人格离开那地方离开过正在同步看到了你撒地方快乐撒的肌肤轮廓啊就是;来的跨省的人格人格离开那地方离开过" }
}
}
}
}
}
// 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 = "啊哈哈哈哈哈哈哈哈"
}
})
}
} }
} }

View File

@ -7,7 +7,7 @@
// //
import UIKit import UIKit
//import ProHUD import ProHUD
import SnapKit import SnapKit
class ViewController: BaseListVC { class ViewController: BaseListVC {
@ -17,22 +17,39 @@ class ViewController: BaseListVC {
// Do any additional setup after loading the view. // Do any additional setup after loading the view.
title = "\(Bundle.main.infoDictionary?["CFBundleName"] ?? "ProHUD")" title = "\(Bundle.main.infoDictionary?["CFBundleName"] ?? "ProHUD")"
vm.addSection(title: "") { (sec) in vm.addSection(title: "测试项目") { (sec) in
sec.addRow(title: "Toast") { sec.addRow(title: "Toast", subtitle: "横幅控件,支持图片、标题和正文。\n不支持添加按钮,但可以接受一个点击事件。") {
let vc = TestToastVC() let vc = TestToastVC()
vc.title = "Toast" vc.title = "Toast"
self.navigationController?.pushViewController(vc, animated: true) self.navigationController?.pushViewController(vc, animated: true)
} }
sec.addRow(title: "Alert") { sec.addRow(title: "Alert", subtitle: "弹窗控件,支持图片、标题、正文和按钮。\n按钮不设置事件回调时可以自动pop。") {
let vc = TestAlertVC() let vc = TestAlertVC()
vc.title = "Alert" vc.title = "Alert"
self.navigationController?.pushViewController(vc, animated: true) self.navigationController?.pushViewController(vc, animated: true)
} }
sec.addRow(title: "Guard") { sec.addRow(title: "Guard", subtitle: "操作表控件,原生支持标题、副标题、正文和按钮,也可以添加任意视图。") {
let vc = TestGuardVC() let vc = TestGuardVC()
vc.title = "Guard" vc.title = "Guard"
self.navigationController?.pushViewController(vc, animated: true) 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如果弹窗添加了按钮,则持续时间会自动变成永久,除非手动设置。") {
}
} }
} }

View File

@ -47,6 +47,8 @@ public extension ProHUD.Scene {
static var message: ProHUD.Scene { static var message: ProHUD.Scene {
var scene = ProHUD.Scene.init(identifier: "prohud.message") var scene = ProHUD.Scene.init(identifier: "prohud.message")
scene.image = ProHUD.image(named: "prohud.message") scene.image = ProHUD.image(named: "prohud.message")
scene.alertDuration = 2
scene.toastDuration = 5
return scene return scene
} }
static var loading: ProHUD.Scene { static var loading: ProHUD.Scene {