ProHUD将弹窗、横幅、操作表统称为HUD,具有多实例管理机制,有效避免弹窗重叠。样式与逻辑分离,可以完全定制UI。即便如此,使用起来也极其简单:

Alert.push(scene: .loading, title: "正在加载", message: "请稍等片刻")

文档和源码

特性

极其简便

发一个弹窗:

Alert.push(scene: .loading, title: "正在加载", message: "请稍等片刻")

发一个通知横幅:

Toast.push(scene: .warning, title: "设备电量过低", message: "请及时对设备进行充电,以免影响使用。")

接口灵活

例如发一个弹窗:

Alert.push("error") { (alert) in // 这里传入的"error"是这个弹窗的唯一标识
    alert.update { (vm) in
        vm.scene = .error
        vm.title = "同步失败"
        vm.message = "请检查网络是否连接"
        vm.add(action: .default, title: "重试") {
            // do something
        }
        vm.add(action: .cancel, title: "取消", handler: nil)
    }
}

实例管理

避免重复发送同一个实例:

// 这段代码的效果:如果没有 id 为 aaa 的横幅,就弹出一个横幅,如果有,就更新(执行 t.update 中的代码)
Toast.push("aaa") { (t) in
    t.update { (vm) in
        vm.scene = .warning
        vm.title = "这是一条id为aaa的横幅"
        vm.message = "避免重复发布同一条信息"
        vm.duration = 0
    }
}

更新loading的结果:

// 这段代码的效果是:寻找 id 为 loading 的弹窗,如果有就更新内容,如果没有,就不做任何操作
Alert.find("loading") { (a) in
    a.update { (vm) in
        vm.scene = .success
        vm.title = "同步成功"
        vm.message = nil
    }
}

更新为加载失败,并增加重试按钮:

// 更新内容不仅仅是更改文字,还可以增加、删除按钮。
Alert.find("loading") { (a) in
    a.update { (vm) in
        vm.scene = .error
        vm.title = "同步失败"
        vm.message = "请检查网络是否连接"
        vm.add(action: .default, title: "重试") {
            // do something
        }
        vm.add(action: .cancel, title: "取消", handler: nil)
    }
}
  1. 用相似的接口调用ToastAlertGuard
  2. 程序初始化时配置自定义UI样式,快速调用。
  3. 用简便的方法拿到已发布的实例,避免重复发布实例。
  4. 可对已发布的实例进行数据更新。
  5. 横竖屏和iPad布局优化。
  6. 易于扩展,可以很方便的添加任意控件,并处理好布局。
  7. 可对所有实例监听消失事件。

Toast(顶部浮动通知条)

  1. 多个Toast并存策略(平铺)。
  2. 只接收一个点击事件。
  3. 可以预先对不同的场景配置不同的默认值(图标、持续时间)。

Alert(页面中心弹窗)

  1. 多个Alert并存策略(具有景深效果的堆叠)。
  2. 可以预先对不同的场景配置不同的默认值(图标、持续时间)。
  3. 可快速创建具有预先配置的默认样式(Default、Destructive、Cancel)的按钮。
  4. 对已发布的实例进行文本和按钮的更新,包括新增、修改、删除文本和按钮。
  5. 强制退出按钮(防止超时导致页面卡死)。

Guard(页面底部操作表)

  1. 快速创建具有预先配置的默认样式的文本元素(标题、副标题、正文)。
  2. 可快速创建具有预先配置的默认样式(Default、Destructive、Cancel)的按钮。

设计思路

UI与逻辑分离

这个库采用配置UI和调用接口分离的设计,这种思路借鉴了和而泰公共库,我认为这是一种调用比传统UI库方便的同时可定制化能力也比传统UI库强大的设计思路。

简单来说,就是你在AppDelegate中告诉ProHUD,你要的横幅、弹窗、操作表分别是什么样的,如果参数是什么什么,就怎么展示UI。
然后调用的地方就不需要设置UI了,只需要专注于数据,如:

Alert.push(scene: .loading, title: "正在加载", message: "请稍等片刻")

这样就发出了一个弹窗,而弹窗的样式,则在AppDelegate中以及预先配置好了。我使用了scene这个灵活的参数,你可以自己扩展场景,例如:

extension ProHUD.Scene {
    static var confirm: ProHUD.Scene {
        var scene = ProHUD.Scene(identifier: "confirm")
        scene.image = UIImage(named: "ProHUDMessage")
        return scene
    }
    static var delete: ProHUD.Scene {
        var scene = ProHUD.Scene(identifier: "delete")
        scene.image = UIImage(named: "ProHUDTrash")
        scene.title = "确认删除"
        scene.message = "此操作不可撤销"
        return scene
    }
    static var buy: ProHUD.Scene {
        var scene = ProHUD.Scene(identifier: "buy")
        scene.image = UIImage(named: "ProHUDBuy")
        scene.title = "确认付款"
        scene.message = "一旦购买拒不退款"
        return scene
    }
}

一个scene就可以理解成一套模板。

极端场景

很多库没有多实例管理,很容易出现简单粗暴的视图重叠现象,ProHUD针对不同场景做了不同的优化,对于横幅来说,可以平铺显示,像系统的通知中心一样,你可以拖拽向上移除。对于弹窗来说,我给底层的弹窗做了景深效果处理,使得看起来不像是BUG。

03-05 20:38