mirror of https://github.com/xaoxuu/ProHUD
代码优化
This commit is contained in:
parent
ccaad1d13d
commit
a37cb52b79
|
@ -110,7 +110,7 @@ class DemoAlertVC: ListVC {
|
|||
alert.config.customButton { button in
|
||||
button.titleLabel?.font = .systemFont(ofSize: 15)
|
||||
}
|
||||
alert.vm?.message = "为了维护社区氛围,上麦用户需进行主播认证"
|
||||
alert.title = "为了维护社区氛围,上麦用户需进行主播认证"
|
||||
alert.onViewDidLoad { vc in
|
||||
guard let alert = vc as? AlertTarget else {
|
||||
return
|
||||
|
@ -140,7 +140,7 @@ class DemoAlertVC: ListVC {
|
|||
alert.config.customButton { button in
|
||||
button.titleLabel?.font = .systemFont(ofSize: 15)
|
||||
}
|
||||
alert.vm?.message = "本次消费需要你支付999软妹豆,确认支付吗?"
|
||||
alert.title = "本次消费需要你支付999软妹豆,确认支付吗?"
|
||||
alert.config.customActionStack { stack in
|
||||
stack.spacing = 0
|
||||
stack.axis = .vertical // 竖排按钮
|
||||
|
@ -193,8 +193,7 @@ class DemoAlertVC: ListVC {
|
|||
}
|
||||
section.add(title: "标题 + 正文 + 按钮") {
|
||||
Alert { alert in
|
||||
alert.vm?.title = "标题"
|
||||
alert.vm?.message = "这是一段正文,长度超出最大宽度时会自动换行"
|
||||
alert.vm = .title("标题").message("这是一段正文,长度超出最大宽度时会自动换行")
|
||||
alert.add(action: "取消", style: .gray)
|
||||
alert.add(action: "删除", style: .destructive) { alert in
|
||||
// 自定义了按钮事件之后,需要手动pop弹窗
|
||||
|
@ -301,8 +300,7 @@ class DemoAlertVC: ListVC {
|
|||
section.add(title: "多层级弹窗") {
|
||||
func f(i: Int) {
|
||||
Alert { alert in
|
||||
alert.vm?.title = "第\(i)次弹"
|
||||
alert.vm?.message = "每次都是一个新的实例覆盖在上一个弹窗上面,而背景不会叠加变深。"
|
||||
alert.vm = .title("第\(i)次弹").message("每次都是一个新的实例覆盖在上一个弹窗上面,而背景不会叠加变深。")
|
||||
alert.add(action: "取消", style: .gray)
|
||||
alert.add(action: "增加一个") { alert in
|
||||
f(i: i + 1)
|
||||
|
@ -338,7 +336,7 @@ class DemoAlertVC: ListVC {
|
|||
let vc = UIViewController()
|
||||
vc.title = "页面"
|
||||
vc.view.backgroundColor = .systemYellow
|
||||
let alert = Alert(.loading.title("正在加载").message("这个弹窗被放在指定容器中")).target
|
||||
let alert = AlertTarget(.loading.title("正在加载").message("这个弹窗被放在指定容器中"))
|
||||
alert.add(action: "返回上一页") { alert in
|
||||
vc.dismiss(animated: true)
|
||||
}
|
||||
|
|
|
@ -35,9 +35,8 @@ class DemoCapsuleVC: ListVC {
|
|||
}
|
||||
}
|
||||
section.add(title: "延迟显示") {
|
||||
// 也可以创建一个空白实例,在需要的时候再push
|
||||
let obj = Capsule().target
|
||||
obj.vm = .message("状态胶囊控件,用于状态显示,一个主程序窗口只有一个状态胶囊实例。")
|
||||
// 也可以手动创建一个Target实例,在需要的时候再push
|
||||
let obj = CapsuleTarget(.message("状态胶囊控件,用于状态显示,一个主程序窗口只有一个状态胶囊实例。"))
|
||||
// ... 在需要的时候手动push
|
||||
DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
|
||||
obj.push()
|
||||
|
@ -55,7 +54,7 @@ class DemoCapsuleVC: ListVC {
|
|||
|
||||
list.add(title: "默认布局:图文") { section in
|
||||
section.add(title: "下载进度") {
|
||||
let capsule = Capsule().target
|
||||
let capsule = CapsuleTarget()
|
||||
capsule.vm = .message("正在下载").icon(.init(systemName: "arrow.down.circle.fill")).duration(.infinity)
|
||||
capsule.update(progress: 0)
|
||||
capsule.push()
|
||||
|
|
|
@ -79,7 +79,7 @@ class DemoToastVC: ListVC {
|
|||
section.add(title: "图标 + 标题 + 正文") {
|
||||
let s1 = "笑容正在加载"
|
||||
let s2 = "这通常不会太久"
|
||||
let toast = Toast(.loading.title(s1).message(s2)).target
|
||||
let toast = ToastTarget(.loading.title(s1).message(s2))
|
||||
toast.push()
|
||||
toast.update(progress: 0)
|
||||
updateProgress(in: 4) { percent in
|
||||
|
@ -186,9 +186,7 @@ class DemoToastVC: ListVC {
|
|||
}
|
||||
section.add(title: "不存在就创建,存在就更新") {
|
||||
i += 1
|
||||
Toast.lazyPush(identifier: "loading") { toast in
|
||||
toast.vm = .loading.title("正在加载\(i)").message("这条消息不会重复显示多条")
|
||||
}
|
||||
Toast(.identifier("loading").title("正在加载\(i)").message("这条消息不会重复显示多条"))
|
||||
}
|
||||
section.add(title: "如果存在就更新,如果不存在就忽略") {
|
||||
i += 1
|
||||
|
|
|
@ -21,9 +21,17 @@ open class AlertProvider: HUDProvider<AlertViewModel, AlertTarget> {
|
|||
/// - vm: 数据模型
|
||||
/// - initializer: 自定义的初始化代码
|
||||
@discardableResult public convenience init(_ vm: ViewModel, initializer: ((_ alert: Target) -> Void)?) {
|
||||
self.init { alert in
|
||||
alert.vm = vm
|
||||
initializer?(alert)
|
||||
if let id = vm.identifier, id.count > 0 {
|
||||
Self.lazyPush(identifier: id) { target in
|
||||
target.vm = vm
|
||||
initializer?(target)
|
||||
}
|
||||
self.init(initializer: nil)
|
||||
} else {
|
||||
self.init { target in
|
||||
target.vm = vm
|
||||
initializer?(target)
|
||||
}
|
||||
}
|
||||
}
|
||||
/// 根据ViewModel创建一个Target并显示
|
||||
|
|
|
@ -9,6 +9,8 @@ import UIKit
|
|||
|
||||
open class AlertTarget: BaseController, HUDTargetType {
|
||||
|
||||
public typealias ViewModel = AlertViewModel
|
||||
|
||||
public lazy var config: AlertConfiguration = {
|
||||
var cfg = AlertConfiguration()
|
||||
AlertConfiguration.customGlobalConfig?(cfg)
|
||||
|
@ -74,7 +76,11 @@ open class AlertTarget: BaseController, HUDTargetType {
|
|||
}()
|
||||
|
||||
/// 视图模型
|
||||
@objc public var vm: AlertViewModel?
|
||||
@objc public var vm: AlertViewModel? {
|
||||
didSet {
|
||||
vm?.vc = self
|
||||
}
|
||||
}
|
||||
|
||||
public override var title: String? {
|
||||
didSet {
|
||||
|
@ -94,6 +100,11 @@ open class AlertTarget: BaseController, HUDTargetType {
|
|||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
|
||||
public convenience init(_ vm: ViewModel) {
|
||||
self.init()
|
||||
self.vm = vm
|
||||
}
|
||||
|
||||
public override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
reloadData(animated: false)
|
||||
|
|
|
@ -21,9 +21,17 @@ open class CapsuleProvider: HUDProvider<CapsuleViewModel, CapsuleTarget> {
|
|||
/// - vm: 数据模型
|
||||
/// - initializer: 初始化代码
|
||||
@discardableResult public convenience init(_ vm: ViewModel, initializer: ((_ capsule: Target) -> Void)?) {
|
||||
self.init { capsule in
|
||||
capsule.vm = vm
|
||||
initializer?(capsule)
|
||||
if let id = vm.identifier, id.count > 0 {
|
||||
Self.lazyPush(identifier: id) { target in
|
||||
target.vm = vm
|
||||
initializer?(target)
|
||||
}
|
||||
self.init(initializer: nil)
|
||||
} else {
|
||||
self.init { target in
|
||||
target.vm = vm
|
||||
initializer?(target)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -9,7 +9,9 @@ import UIKit
|
|||
|
||||
open class CapsuleTarget: BaseController, HUDTargetType {
|
||||
|
||||
public lazy var config: CapsuleConfiguration = {
|
||||
public typealias ViewModel = CapsuleViewModel
|
||||
|
||||
@objc public lazy var config: CapsuleConfiguration = {
|
||||
var cfg = CapsuleConfiguration()
|
||||
CapsuleConfiguration.customGlobalConfig?(cfg)
|
||||
return cfg
|
||||
|
@ -46,7 +48,11 @@ open class CapsuleTarget: BaseController, HUDTargetType {
|
|||
return lb
|
||||
}()
|
||||
|
||||
public var vm: CapsuleViewModel?
|
||||
@objc public var vm: CapsuleViewModel? {
|
||||
didSet {
|
||||
vm?.vc = self
|
||||
}
|
||||
}
|
||||
|
||||
public override var title: String? {
|
||||
didSet {
|
||||
|
@ -68,6 +74,11 @@ open class CapsuleTarget: BaseController, HUDTargetType {
|
|||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
|
||||
public convenience init(_ vm: ViewModel) {
|
||||
self.init()
|
||||
self.vm = vm
|
||||
}
|
||||
|
||||
public override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
view.layer.shadowRadius = 8
|
||||
|
@ -84,7 +95,7 @@ open class CapsuleTarget: BaseController, HUDTargetType {
|
|||
|
||||
}
|
||||
|
||||
public func onTapped(action: @escaping (_ capsule: CapsuleTarget) -> Void) {
|
||||
@objc public func onTapped(action: @escaping (_ capsule: CapsuleTarget) -> Void) {
|
||||
self.tapActionCallback = action
|
||||
}
|
||||
|
||||
|
|
|
@ -12,6 +12,26 @@ public protocol HUDViewModelType {}
|
|||
/// 数据模型
|
||||
open class BaseViewModel: NSObject, HUDViewModelType {
|
||||
|
||||
/// 在创建target之前临时暂存的id
|
||||
private var tmpStoredIdentifier: String?
|
||||
|
||||
/// 创建target时将指定为此值
|
||||
@objc open var identifier: String? {
|
||||
set {
|
||||
tmpStoredIdentifier = newValue
|
||||
if let id = tmpStoredIdentifier, id.count > 0 {
|
||||
vc?.identifier = id
|
||||
}
|
||||
}
|
||||
get {
|
||||
if let vc = vc {
|
||||
return vc.identifier
|
||||
} else {
|
||||
return tmpStoredIdentifier
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// 图标
|
||||
@objc open var icon: UIImage?
|
||||
@objc var iconURL: URL?
|
||||
|
@ -34,7 +54,15 @@ open class BaseViewModel: NSObject, HUDViewModelType {
|
|||
}
|
||||
}
|
||||
|
||||
@objc public required override init() {
|
||||
weak var vc: BaseController? {
|
||||
didSet {
|
||||
if let id = tmpStoredIdentifier {
|
||||
vc?.identifier = id
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@objc required public override init() {
|
||||
|
||||
}
|
||||
|
||||
|
@ -70,6 +98,11 @@ open class BaseViewModel: NSObject, HUDViewModelType {
|
|||
// MARK: - convenience func
|
||||
public extension BaseViewModel {
|
||||
|
||||
func identifier(_ identifier: String?) -> Self {
|
||||
self.identifier = identifier
|
||||
return self
|
||||
}
|
||||
|
||||
func icon(_ image: UIImage?) -> Self {
|
||||
self.icon = image
|
||||
return self
|
||||
|
@ -110,6 +143,11 @@ public extension BaseViewModel {
|
|||
// MARK: - example scenes
|
||||
public extension BaseViewModel {
|
||||
|
||||
static func identifier(_ text: String?) -> Self {
|
||||
.init()
|
||||
.identifier(text)
|
||||
}
|
||||
|
||||
// MARK: plain
|
||||
static func title(_ text: String?) -> Self {
|
||||
.init()
|
||||
|
|
|
@ -18,28 +18,23 @@ public protocol HUDProviderType {
|
|||
|
||||
}
|
||||
|
||||
open class HUDProvider<ViewModel: HUDViewModelType, Target: HUDTargetType>: HUDProviderType {
|
||||
|
||||
/// HUD实例
|
||||
public var target: Target
|
||||
open class HUDProvider<ViewModel: HUDViewModelType, Target: HUDTargetType>: NSObject, HUDProviderType {
|
||||
|
||||
/// 根据自定义的初始化代码创建一个Target并显示
|
||||
/// - Parameter initializer: 初始化代码
|
||||
/// - Parameter initializer: 初始化代码(传空值时不会做任何事)
|
||||
@discardableResult public required init(initializer: ((_ target: Target) -> Void)?) {
|
||||
guard let initializer = initializer else {
|
||||
// Provider的作用就是push一个target
|
||||
// 如果没有任何初始化代码就没有target,就是个无意义的Provider
|
||||
// 但为了支持lazyPush(找到已有实例并更新),所以就需要支持无意义的Provider
|
||||
// 详见子类中的 self.init(initializer: nil)
|
||||
return
|
||||
}
|
||||
var t = Target()
|
||||
initializer?(t)
|
||||
self.target = t
|
||||
if (t.vm == nil && initializer == nil) == false {
|
||||
DispatchQueue.main.async {
|
||||
t.push()
|
||||
}
|
||||
initializer(t)
|
||||
DispatchQueue.main.async {
|
||||
t.push()
|
||||
}
|
||||
}
|
||||
|
||||
/// 创建一个空白的实例,不立即显示,需要手动调用target.push()来显示
|
||||
@discardableResult public convenience init() {
|
||||
self.init(initializer: nil)
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -34,7 +34,7 @@ public class ProgressView: UIView {
|
|||
let bgLayer = CAShapeLayer()
|
||||
bgLayer.fillColor = UIColor.clear.cgColor
|
||||
bgLayer.path = path.cgPath
|
||||
bgLayer.strokeColor = UIColor.white.cgColor
|
||||
bgLayer.strokeColor = UIColor.clear.cgColor
|
||||
bgLayer.lineWidth = lineWidth
|
||||
bgLayer.lineCap = .round
|
||||
bgLayer.strokeStart = 0
|
||||
|
|
|
@ -41,7 +41,11 @@ open class SheetTarget: BaseController, HUDTargetType {
|
|||
}
|
||||
}
|
||||
|
||||
public var vm: SheetViewModel? = nil
|
||||
public var vm: SheetViewModel? = nil {
|
||||
didSet {
|
||||
vm?.vc = self
|
||||
}
|
||||
}
|
||||
|
||||
required public override init() {
|
||||
super.init()
|
||||
|
|
|
@ -26,11 +26,17 @@ extension ToastTarget: DefaultLayout {
|
|||
}
|
||||
return
|
||||
}
|
||||
let titleCount = vm?.title?.count ?? 0
|
||||
let bodyCount = vm?.message?.count ?? 0
|
||||
if vm?.icon != nil || vm?.iconURL != nil {
|
||||
if imageView.superview == nil {
|
||||
infoStack.insertArrangedSubview(imageView, at: 0)
|
||||
imageView.snp.makeConstraints { make in
|
||||
make.width.height.equalTo(config.iconSize)
|
||||
if titleCount > 0 && bodyCount > 0 {
|
||||
make.width.height.equalTo(config.iconSize)
|
||||
} else {
|
||||
make.width.equalTo(config.iconSize)
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
@ -42,8 +48,6 @@ extension ToastTarget: DefaultLayout {
|
|||
if textStack.superview == nil {
|
||||
infoStack.addArrangedSubview(textStack)
|
||||
}
|
||||
let titleCount = vm?.title?.count ?? 0
|
||||
let bodyCount = vm?.message?.count ?? 0
|
||||
if titleCount > 0 {
|
||||
textStack.insertArrangedSubview(titleLabel, at: 0)
|
||||
if bodyCount > 0 {
|
||||
|
|
|
@ -21,9 +21,17 @@ open class ToastProvider: HUDProvider<ToastViewModel, ToastTarget> {
|
|||
/// - vm: 数据模型
|
||||
/// - initializer: 自定义的初始化代码
|
||||
@discardableResult public convenience init(_ vm: ViewModel, initializer: ((_ toast: Target) -> Void)?) {
|
||||
self.init { toast in
|
||||
toast.vm = vm
|
||||
initializer?(toast)
|
||||
if let id = vm.identifier, id.count > 0 {
|
||||
Self.lazyPush(identifier: id) { target in
|
||||
target.vm = vm
|
||||
initializer?(target)
|
||||
}
|
||||
self.init(initializer: nil)
|
||||
} else {
|
||||
self.init { target in
|
||||
target.vm = vm
|
||||
initializer?(target)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -9,6 +9,8 @@ import UIKit
|
|||
|
||||
open class ToastTarget: BaseController, HUDTargetType {
|
||||
|
||||
public typealias ViewModel = ToastViewModel
|
||||
|
||||
weak var window: ToastWindow?
|
||||
|
||||
public lazy var config: ToastConfiguration = {
|
||||
|
@ -84,7 +86,11 @@ open class ToastTarget: BaseController, HUDTargetType {
|
|||
public var isRemovable = true
|
||||
|
||||
/// 视图模型
|
||||
@objc public var vm: ToastViewModel?
|
||||
@objc public var vm: ToastViewModel? {
|
||||
didSet {
|
||||
vm?.vc = self
|
||||
}
|
||||
}
|
||||
|
||||
private var tapActionCallback: ((_ toast: ToastTarget) -> Void)?
|
||||
|
||||
|
@ -103,7 +109,12 @@ open class ToastTarget: BaseController, HUDTargetType {
|
|||
}
|
||||
|
||||
required public init?(coder: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
super.init(coder: coder)
|
||||
}
|
||||
|
||||
public convenience init(_ vm: ViewModel) {
|
||||
self.init()
|
||||
self.vm = vm
|
||||
}
|
||||
|
||||
public override func viewDidLoad() {
|
||||
|
|
Loading…
Reference in New Issue