This commit is contained in:
xaoxuu 2020-06-23 20:16:12 +08:00
parent 539ad04623
commit ad3576cf6f
8 changed files with 589 additions and 487 deletions

View File

@ -30,7 +30,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
// a.bodyFont = .regular(17)
// a.boldTextFont = .bold(18)
// a.buttonFont = .bold(18)
a.forceQuitTimer = 3
a.forceQuitTimer = 5 // 便
}
// cfg.toast { (t) in
// t.titleFont = .bold(18)
@ -78,7 +78,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
extension ProHUD.Scene {
static var delete: ProHUD.Scene {
var scene = ProHUD.Scene(identifier: "delete")
var scene = ProHUD.Scene(identifier: "prohud.delete")
scene.image = UIImage(named: "prohud.trash")
scene.title = "确认删除"
scene.message = "此操作不可撤销"

View File

@ -8,18 +8,46 @@
import UIKit
typealias Callback = () -> Void
struct Table {
var sections = [Section]()
mutating func addSection(title: String, callback: @escaping (inout Section) -> Void) {
var sec = Section()
sec.header = title
callback(&sec)
sections.append(sec)
}
}
struct Section {
var header = ""
var footer = ""
var rows = [Row]()
mutating func addRow(title: String, subtitle: String? = nil, callback: @escaping Callback) {
rows.append(Row(title: title, subtitle: subtitle, callback: callback))
}
}
struct Row {
var title: String
var subtitle: String?
var callback: Callback
}
class BaseListVC: UIViewController {
var ts = [[String]]()
var cs = [[Callback]]()
var vm = Table()
var secs = [Section]()
lazy var tableView: UITableView = {
let tv = UITableView()
let tv = UITableView(frame: .zero, style: .grouped)
return tv
}()
var titles: [String] {
return ["Toast", "Alert", "Guard"]
}
override func viewDidLoad() {
super.viewDidLoad()
@ -27,29 +55,47 @@ class BaseListVC: UIViewController {
view.addSubview(tableView)
tableView.dataSource = self
tableView.delegate = self
tableView.register(UITableViewCell.self, forCellReuseIdentifier: "cell")
tableView.snp.makeConstraints { (mk) in
mk.edges.equalToSuperview()
}
}
}
extension BaseListVC: UITableViewDataSource, UITableViewDelegate {
func numberOfSections(in tableView: UITableView) -> Int {
return vm.sections.count
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return titles.count
return vm.sections[section].rows.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
cell.textLabel?.text = titles[indexPath.row]
let cell: UITableViewCell
if let c = tableView.dequeueReusableCell(withIdentifier: "cell") {
cell = c
} else {
cell = UITableViewCell(style: .subtitle, reuseIdentifier: "cell")
cell.textLabel?.numberOfLines = 0
cell.detailTextLabel?.textColor = .gray
cell.detailTextLabel?.numberOfLines = 0
}
cell.textLabel?.text = vm.sections[indexPath.section].rows[indexPath.row].title
cell.detailTextLabel?.text = vm.sections[indexPath.section].rows[indexPath.row].subtitle
return cell
}
func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
return vm.sections[section].header
}
func tableView(_ tableView: UITableView, titleForFooterInSection section: Int) -> String? {
return vm.sections[section].footer
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath, animated: true)
vm.sections[indexPath.section].rows[indexPath.row].callback()
}
}

View File

@ -9,91 +9,109 @@
import UIKit
import ProHUD
// 2
func loadingSuccessAfter2Seconds() {
DispatchQueue.main.asyncAfter(deadline: .now()+2) {
Alert.find("loading", last: { (a) in
a.update { (vm) in
vm.scene = .success
vm.title = "同步成功"
vm.message = nil
}
})
}
}
class TestAlertVC: BaseListVC {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
vm.addSection(title: "最简单的写法") { (sec) in
sec.addRow(title: "Alert.push(scene: .loading)") {
Alert.push(scene: .loading)
}
sec.addRow(title: "Alert.push(scene: .success)") {
Alert.push(scene: .success)
}
sec.addRow(title: "Alert.push(scene: .warning)") {
Alert.push(scene: .warning)
}
sec.addRow(title: "Alert.push(scene: .error)") {
Alert.push(scene: .error)
}
sec.addRow(title: "Alert.push(scene: .failure)") {
Alert.push(scene: .failure)
}
sec.footer = "这些是自带的场景,可以重写已有场景,或者扩展新的场景。"
}
override var titles: [String] {
return ["极端场景:正在同步(超时未处理)",
"场景同步成功写法1",
"场景同步成功写法2",
"场景:同步失败和重试",
"极端场景:短时间内调用了多次同一个弹窗",
"极端场景:多个不同的弹窗重叠",
"测试较长的标题和内容",
"测试特别长的标题和内容",
"场景:正在同步(更新进度)"]
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath, animated: true)
let row = indexPath.row
if row == 0 {
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()
}
}
}
}
f()
} else if row == 1 {
Alert.push() { (a) in
a.identifier = "loading"
a.startRotate()
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 = "请稍等片刻"
}
}
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 == 2 {
let a = Alert.push() { (a) in
a.identifier = "loading"
}
a.startRotate()
}
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 = "请稍等片刻"
}
DispatchQueue.main.asyncAfter(deadline: .now()+2) {
Alert.find("loading", last: { (a) in
loadingSuccessAfter2Seconds()
}
// MARK:
sec.addRow(title: "场景:正在同步(更新进度)") {
Alert.push("progress") { (a) in
a.update { (vm) in
vm.scene = .loading
vm.title = "正在同步"
vm.message = "请稍等片刻"
}
a.startRotate()
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()
}
} else if row == 3 {
Alert.push() { (a) in
a.identifier = "loading"
}
}
}
}
}
// MARK:
sec.addRow(title: "场景:同步失败和重试(布局变化)") {
Alert.push("loading", scene: .loading)
func loading() {
Alert.find("loading", last: { (a) in
Alert.find("loading") { (a) in
a.update { (vm) in
vm.scene = .loading
vm.title = "正在同步"
@ -112,22 +130,42 @@ class TestAlertVC: BaseListVC {
vm.add(action: .cancel, title: "取消", handler: nil)
}
}
})
}
}
loading()
} else if row == 4 {
}
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()
}
}
}
}
f()
}
// MARK:
sec.addRow(title: "极端场景:短时间内调用了多次同一个弹窗", subtitle: "多次调用页面弹窗应该是毫无变化的。本例中4秒内调用了6次") {
func loading(_ index: Int = 1) {
if let _ = Alert.find("loading").last {
Toast.push("loading-tip") { (t) in
t.update { (vm) in
vm.title = "此时又调用了一次相同的弹窗 x\(index)"
}
t.pulse()
}
} else {
Alert.push("loading") { (a) in
if Alert.find("loading").count == 0 {
Alert.push("loading", scene: .loading) { (a) in
a.update { (vm) in
vm.scene = .loading
vm.title = "正在加载"
}
a.startRotate()
@ -150,7 +188,9 @@ class TestAlertVC: BaseListVC {
DispatchQueue.main.asyncAfter(deadline: .now()+4) {
loading(6)
}
} else if row == 5 {
}
// MARK:
sec.addRow(title: "极端场景:多个不同的弹窗重叠", subtitle: "多个弹窗不得不重叠的时候ProHUD的景深处理可以使其看起来舒服一些。") {
func f(_ i: Int) {
Alert.push() { (a) in
a.startRotate()
@ -171,7 +211,16 @@ class TestAlertVC: BaseListVC {
DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
f(4)
}
} else if row == 6 {
}
}
vm.addSection(title: "") { (sec) in
// MARK:
sec.addRow(title: "测试较长的标题和内容") {
Alert.push() { (a) in
a.update { (vm) in
vm.scene = .confirm
@ -180,7 +229,9 @@ class TestAlertVC: BaseListVC {
vm.add(action: .default, title: "我知道了", handler: nil)
}
}
} else if row == 7 {
}
// MARK:
sec.addRow(title: "测试特别长的标题和内容", subtitle: "这种情况编码阶段就可以避免,所以没有做特别处理,请控制内容长度不要过长。") {
Alert.push() { (a) in
a.update { (vm) in
vm.scene = .warning
@ -189,39 +240,21 @@ class TestAlertVC: BaseListVC {
vm.add(action: .default, title: "我知道了", handler: nil)
}
}
} else if row == 8 {
Alert.push("progress") { (a) in
a.update { (vm) in
vm.scene = .loading
vm.title = "正在同步"
vm.message = "请稍等片刻"
}
a.startRotate()
a.update(progress: 0)
let s = DispatchSemaphore(value: 1)
DispatchQueue.global().async {
for i in 0 ... 5 {
s.wait()
DispatchQueue.main.async {
Alert.find("progress", last: { (a) in
a.update(progress: CGFloat(i)/5)
print("\(CGFloat(i)/5)")
if i == 5 {
a.update { (vm) in
vm.scene = .success
vm.title = "同步成功"
vm.message = nil
}
}
})
DispatchQueue.main.asyncAfter(deadline: .now()+1) {
s.signal()
}
}
}
}
// MARK:
sec.addRow(title: "只有标题") {
Alert.push(scene: .default, title: "标题")
}
// MARK:
sec.addRow(title: "只有消息") {
Alert.push(scene: .default, message: "这是消息")
}
// MARK:
sec.addRow(title: "既没有标题也没有消息") {
Alert.push("a")
}
}
}
func simulateSync() {

View File

@ -15,17 +15,9 @@ class TestGuardVC: BaseListVC {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
override var titles: [String] {
return ["场景:删除菜单", "场景:升级至专业版", "场景:隐私协议页面", "对比原生的ActionSheet", "对比原生Present效果"]
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath, animated: true)
let row = indexPath.row
if row == 0 {
vm.addSection(title: "") { (sec) in
// MARK:
sec.addRow(title: "场景:删除菜单") {
Guard.push("del") { (vc) in
vc.update { (vm) in
vm.add(action: .destructive, title: "删除") { [weak vc] in
@ -42,7 +34,10 @@ class TestGuardVC: BaseListVC {
vm.add(action: .cancel, title: "取消", handler: nil)
}
}
} else if row == 1 {
}
// MARK:
sec.addRow(title: "场景:升级至专业版") {
// id
Guard.push("pro") { (vc) in
vc.identifier = "pro"
@ -84,7 +79,10 @@ class TestGuardVC: BaseListVC {
vm.add(action: .cancel, title: "取消", handler: nil)
}
}
} else if row == 2 {
}
// MARK:
sec.addRow(title: "场景:隐私协议页面") {
Guard.push("license") { (vc) in
vc.isFullScreen = true
vc.update { (vm) in
@ -104,20 +102,27 @@ class TestGuardVC: BaseListVC {
}
}
}
} else if row == 3 {
}
// MARK: ActionSheet
sec.addRow(title: "对比原生的ActionSheet") {
let ac = UIAlertController(title: "Title", message: "message", preferredStyle: .actionSheet)
let ok = UIAlertAction(title: "OK", style: .default, handler: nil)
let cancel = UIAlertAction(title: "Cancel", style: .cancel, handler: nil)
ac.addAction(ok)
ac.addAction(cancel)
ac.popoverPresentationController?.sourceView = tableView.cellForRow(at: indexPath)
ac.popoverPresentationController?.sourceView = self.view
self.present(ac, animated: true, completion: nil)
} else if row == 4 {
}
// MARK: Present
sec.addRow(title: "对比原生Present效果") {
let vc = UIViewController()
vc.view.backgroundColor = .white
vc.title = "ceshi"
present(vc, animated: true, completion: nil)
self.present(vc, animated: true, completion: nil)
}
}
}

View File

@ -9,44 +9,25 @@
import UIKit
import ProHUD
typealias Callback2 = (String) -> Void
class TestToastVC: BaseListVC {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
override var titles: [String] {
return ["场景:正在同步",
"场景:正在同步(更新进度)",
"场景:同步成功",
"场景:同步失败",
"场景:设备电量过低",
"传入指定图标",
"禁止手势移除",
"组合使用示例",
"避免重复发布同一条信息",
"根据id查找并修改实例",
"测试较长的标题和内容",
"测试特别长的标题和内容",
"测试只有title",
"测试只有message",
"自定义旋转的图片"]
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath, animated: true)
let row = indexPath.row
if row == 0 {
vm.addSection(title: "基本场景") { (sec) in
// MARK:
sec.addRow(title: "场景:正在同步") {
Toast.push(scene: .loading, title: "正在同步", message: "请稍等片刻") { (vm) in
vm.identifier = "loading"
}.startRotate()
simulateSync()
} else if row == 1 {
if let _ = Toast.find("progress").last {
} else {
self.simulateSync()
}
// MARK:
sec.addRow(title: "场景:正在同步(更新进度)") {
if Toast.find("progress").count == 0 {
Toast.push("progress") { (t) in
t.update { (vm) in
vm.scene = .loading
@ -79,14 +60,17 @@ class TestToastVC: BaseListVC {
}
}
}
} else if row == 2 {
}
// MARK:
sec.addRow(title: "场景:同步成功") {
let t = Toast.push(scene: .success, title: "同步成功", message: "点击查看详情")
t.didTapped { [weak self, weak t] in
self?.presentEmptyVC(title: "详情")
t?.pop()
}
} else if row == 3 {
}
// MARK:
sec.addRow(title: "场景:同步失败") {
Toast.push(scene: .error, title: "同步失败", message: "请稍后重试。点击查看详情") { (vc) in
vc.update { (vm) in
vm.duration = 0
@ -96,10 +80,9 @@ class TestToastVC: BaseListVC {
vc?.pop()
}
}
} else if row == 4 {
Toast.push(scene: .warning, title: "设备电量过低", message: "请及时对设备进行充电,以免影响使用。")
} else if row == 5 {
}
// MARK:
sec.addRow(title: "场景:设备电量过低") {
Toast.push(scene: .default, title: "传入指定图标测试", message: "这是消息内容") { (vc) in
vc.update { (vm) in
if #available(iOS 13.0, *) {
@ -110,14 +93,25 @@ class TestToastVC: BaseListVC {
}
}
}
} else if row == 6 {
}
}
vm.addSection(title: "") { (sec) in
// MARK:
sec.addRow(title: "传入指定图标") {
Toast.push(scene: .warning, title: "设备电量过低", message: "请及时对设备进行充电,以免影响使用。")
}
// MARK:
sec.addRow(title: "禁止手势移除") {
Toast.push(scene: .default, title: "禁止手势移除", message: "这条消息无法通过向上滑动移出屏幕。5秒后自动消失每次拖拽都会刷新倒计时。") { (vc) in
vc.isRemovable = false
vc.update { (vm) in
vm.duration = 5
}
}
} else if row == 7 {
}
// MARK: 使
sec.addRow(title: "组合使用示例") {
Toast.push(scene: .message, title: "好友邀请", message: "你收到一条好友邀请,点击查看详情。", duration: 10) { (vc) in
vc.identifier = "xxx"
vc.didTapped { [weak vc] in
@ -135,7 +129,9 @@ class TestToastVC: BaseListVC {
}
}
}
} else if row == 8 {
}
// MARK:
sec.addRow(title: "避免重复发布同一条信息") {
if let t = Toast.find("aaa").last {
t.pulse()
t.update() { (vm) in
@ -150,7 +146,9 @@ class TestToastVC: BaseListVC {
}
}
}
} else if row == 9 {
}
// MARK: id
sec.addRow(title: "根据id查找并修改实例") {
Toast.push("aaa") { (t) in
t.update { (vm) in
vm.scene = .success
@ -159,7 +157,9 @@ class TestToastVC: BaseListVC {
}
t.pulse()
}
} else if row == 10 {
}
// MARK:
sec.addRow(title: "测试较长的标题和内容") {
Toast.push() { (a) in
a.update { (vm) in
vm.title = "正在同步看到了你撒地方快乐撒的肌肤轮廓啊就是;来的跨省的人格人格离开那地方离开过"
@ -167,7 +167,9 @@ class TestToastVC: BaseListVC {
}
}
} else if row == 11 {
}
// MARK:
sec.addRow(title: "测试特别长的标题和内容") {
Toast.push() { (a) in
a.update { (vm) in
vm.title = "正在同步看到了你撒地方快乐撒的肌肤轮廓啊就是;来的跨省的人格人格离开那地方离开过正在同步看到了你撒地方快乐撒的肌肤轮廓啊就是;来的跨省的人格人格离开那地方离开过正在同步看到了你撒地方快乐撒的肌肤轮廓啊就是;来的跨省的人格人格离开那地方离开过"
@ -175,7 +177,9 @@ class TestToastVC: BaseListVC {
}
}
} else if row == 12 {
}
// MARK: title
sec.addRow(title: "测试只有title") {
Toast.push() { (a) in
a.update { (vm) in
vm.scene = .warning
@ -183,7 +187,9 @@ class TestToastVC: BaseListVC {
}
}
} else if row == 13 {
}
// MARK: message
sec.addRow(title: "测试只有message") {
Toast.push() { (a) in
a.update { (vm) in
vm.scene = .warning
@ -191,8 +197,9 @@ class TestToastVC: BaseListVC {
}
}
} else if row == 14 {
}
// MARK:
sec.addRow(title: "自定义旋转的图片") {
Toast.push(scene: .privacy, title: "正在授权", message: "请稍等片刻") { (t) in
t.identifier = "loading"
let imgv = UIImageView(image: UIImage(named: "prohud.rainbow.circle"))
@ -203,14 +210,17 @@ class TestToastVC: BaseListVC {
}
t.startRotate(imgv.layer, speed: 4)
}
simulateSync()
self.simulateSync()
}
}
}
func simulateSync() {
DispatchQueue.main.asyncAfter(deadline: .now() + 10) {
Toast.find("loading", last: { (t) in
t.update { (vm) in
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

@ -16,28 +16,26 @@ class ViewController: BaseListVC {
super.viewDidLoad()
// Do any additional setup after loading the view.
title = "\(Bundle.main.infoDictionary?["CFBundleName"] ?? "ProHUD")"
}
override var titles: [String] {
return ["Toast", "Alert", "Guard"]
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath, animated: true)
if indexPath.row == 0 {
vm.addSection(title: "") { (sec) in
sec.addRow(title: "Toast") {
let vc = TestToastVC()
vc.title = titles[indexPath.row]
navigationController?.pushViewController(vc, animated: true)
} else if indexPath.row == 1 {
vc.title = "Toast"
self.navigationController?.pushViewController(vc, animated: true)
}
sec.addRow(title: "Alert") {
let vc = TestAlertVC()
vc.title = titles[indexPath.row]
navigationController?.pushViewController(vc, animated: true)
} else {
vc.title = "Alert"
self.navigationController?.pushViewController(vc, animated: true)
}
sec.addRow(title: "Guard") {
let vc = TestGuardVC()
vc.title = titles[indexPath.row]
navigationController?.pushViewController(vc, animated: true)
vc.title = "Guard"
self.navigationController?.pushViewController(vc, animated: true)
}
}
}
}

View File

@ -63,10 +63,10 @@ public extension ProHUD {
/// - Parameter title:
/// - Parameter message:
/// - Parameter icon:
public convenience init(scene: Scene = .default, title: String? = nil, message: String? = nil, actions: ((Alert) -> Void)? = nil) {
public convenience init(scene: Scene?, title: String? = nil, message: String? = nil, actions: ((Alert) -> Void)? = nil) {
self.init()
vm.vc = self
vm.scene = scene
vm.scene = scene ?? .default
vm.title = title
vm.message = message
actions?(self)
@ -148,7 +148,7 @@ public extension Alert {
}
///
///
/// - Parameter callback:
func didForceQuit(_ callback: (() -> Void)?) {
vm.forceQuitCallback = callback
@ -177,14 +177,19 @@ public extension Alert {
/// - identifier:
/// - toast:
/// - Returns:
@discardableResult class func push(_ identifier: String, instance: @escaping (Alert) -> Void) -> Alert {
@discardableResult class func push(_ identifier: String, scene: ProHUD.Scene? = nil, instance: ((Alert) -> Void)? = nil) -> Alert {
if let a = find(identifier).last {
instance(a)
if let s = scene, s != a.vm.scene {
a.update { (vm) in
vm.scene = s
}
}
instance?(a)
return a
} else {
return Alert() { (aa) in
return Alert(scene: scene) { (aa) in
aa.identifier = identifier
instance(aa)
instance?(aa)
}.push()
}
}

View File

@ -75,11 +75,11 @@ 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: ((Toast) -> Void)? = nil) {
public convenience init(scene: Scene?, title: String? = nil, message: String? = nil, icon: UIImage? = nil, duration: TimeInterval? = nil, actions: ((Toast) -> Void)? = nil) {
self.init()
vm.vc = self
vm.scene = scene
vm.scene = scene ?? .default
vm.title = title
vm.message = message
vm.icon = icon
@ -227,14 +227,19 @@ public extension Toast {
/// - identifier:
/// - toast:
/// - Returns:
@discardableResult class func push(_ identifier: String, instance: @escaping (Toast) -> Void) -> Toast {
@discardableResult class func push(_ identifier: String, scene: ProHUD.Scene? = nil, instance: ((Toast) -> Void)? = nil) -> Toast {
if let t = find(identifier).last {
instance(t)
if let s = scene, s != t.vm.scene {
t.update { (vm) in
vm.scene = s
}
}
instance?(t)
return t
} else {
return Toast() { (tt) in
return Toast(scene: scene) { (tt) in
tt.identifier = identifier
instance(tt)
instance?(tt)
}.push()
}
}