diff --git a/Example/Example/Info.plist b/Example/Example/Info.plist
index ff0a7ed..ed7fc0e 100644
--- a/Example/Example/Info.plist
+++ b/Example/Example/Info.plist
@@ -33,7 +33,7 @@
UIRequiresFullScreen
UIStatusBarHidden
-
+
UIStatusBarStyle
UIStatusBarStyleDefault
UISupportedInterfaceOrientations
diff --git a/Example/Example/ViewController.swift b/Example/Example/ViewController.swift
index a29bf6e..935c2b1 100644
--- a/Example/Example/ViewController.swift
+++ b/Example/Example/ViewController.swift
@@ -16,17 +16,12 @@ class ViewController: UIViewController {
// Do any additional setup after loading the view.
- ProHUD.configAlert { (alert) in
- alert.minimizeTimeout = 3
-
- }
- ProHUD.configGuard { (g) in
- g.tintColor = .success
- }
- ProHUD.configToast { (toast) in
-// toast.backgroundColorForScene { (scene) -> UIColor? in
-// return UIColor.yellow
-// }
+ ProHUD.config { (cfg) in
+// cfg.enableDebugPrint = false
+ cfg.alert { (a) in
+ a.forceQuitTimer = 2
+ }
+// cfg.primaryLabelColor = .purple
}
}
@@ -71,7 +66,8 @@ class ViewController: UIViewController {
let g = ProHUD.Guard(title: "请求权限", message: "请打开相机权限开关,否则无法进行测量。")
// g.view.tintColor = .warning
// g.loadBody(g.description)
-
+ g.loadTitle("呵呵")
+ g.loadBody("请打开相机权限开关,否则无法进行测量。请打开相机权限开关,否则无法进行测量。")
g.loadButton(style: .default, title: "测试弹窗", action: { [weak self] in
self?.testToast()
})
diff --git a/ProHUD.xcodeproj/project.pbxproj b/ProHUD.xcodeproj/project.pbxproj
index 011e03f..11e0a8e 100644
--- a/ProHUD.xcodeproj/project.pbxproj
+++ b/ProHUD.xcodeproj/project.pbxproj
@@ -12,8 +12,6 @@
CD16490F22EF09D50077988C /* AlertView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD16490E22EF09D50077988C /* AlertView.swift */; };
CD16491222EF0D900077988C /* HUDView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD16491122EF0D900077988C /* HUDView.swift */; };
CD16491422EF12220077988C /* ProHUD.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = CD16491322EF12220077988C /* ProHUD.xcassets */; };
- CD67039022E7F7B60072C96A /* HUDForToast.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD67038F22E7F7B60072C96A /* HUDForToast.swift */; };
- CD67039222E7F7BC0072C96A /* HUDForGuard.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD67039122E7F7BC0072C96A /* HUDForGuard.swift */; };
CD6CD86C22F1858F00F4FD4A /* ToastModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD6CD86B22F1858F00F4FD4A /* ToastModel.swift */; };
CD6CD86E22F185A000F4FD4A /* ToastView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD6CD86D22F185A000F4FD4A /* ToastView.swift */; };
CD6CD87022F185A700F4FD4A /* ToastController.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD6CD86F22F185A700F4FD4A /* ToastController.swift */; };
@@ -35,8 +33,6 @@
CD16490E22EF09D50077988C /* AlertView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AlertView.swift; sourceTree = ""; };
CD16491122EF0D900077988C /* HUDView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HUDView.swift; sourceTree = ""; };
CD16491322EF12220077988C /* ProHUD.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = ProHUD.xcassets; sourceTree = ""; };
- CD67038F22E7F7B60072C96A /* HUDForToast.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HUDForToast.swift; sourceTree = ""; };
- CD67039122E7F7BC0072C96A /* HUDForGuard.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HUDForGuard.swift; sourceTree = ""; };
CD6CD86B22F1858F00F4FD4A /* ToastModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ToastModel.swift; sourceTree = ""; };
CD6CD86D22F185A000F4FD4A /* ToastView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ToastView.swift; sourceTree = ""; };
CD6CD86F22F185A700F4FD4A /* ToastController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ToastController.swift; sourceTree = ""; };
@@ -122,8 +118,6 @@
CD95D21F22E72C4C007559A3 /* ProHUD.h */,
CD16491322EF12220077988C /* ProHUD.xcassets */,
CD95D26A22E72DB3007559A3 /* ProHUD.swift */,
- CD67038F22E7F7B60072C96A /* HUDForToast.swift */,
- CD67039122E7F7BC0072C96A /* HUDForGuard.swift */,
CDB6A07C22EEF19D00AF6CF0 /* HUDConfig.swift */,
CDB6A07A22EEF06500AF6CF0 /* HUDController.swift */,
CD16491122EF0D900077988C /* HUDView.swift */,
@@ -219,12 +213,10 @@
CD6CD87B22F185D600F4FD4A /* GuardView.swift in Sources */,
CD95D26922E72DA1007559A3 /* AlertController.swift in Sources */,
CD6CD87922F185D000F4FD4A /* GuardConfig.swift in Sources */,
- CD67039222E7F7BC0072C96A /* HUDForGuard.swift in Sources */,
CDB6A07D22EEF19D00AF6CF0 /* HUDConfig.swift in Sources */,
CD16490F22EF09D50077988C /* AlertView.swift in Sources */,
CD6CD86E22F185A000F4FD4A /* ToastView.swift in Sources */,
CD6CD87222F185AF00F4FD4A /* ToastConfig.swift in Sources */,
- CD67039022E7F7B60072C96A /* HUDForToast.swift in Sources */,
CD6CD87522F185C200F4FD4A /* GuardController.swift in Sources */,
CD6CD87022F185A700F4FD4A /* ToastController.swift in Sources */,
CD95D26B22E72DB3007559A3 /* ProHUD.swift in Sources */,
diff --git a/ProHUD/Alert/AlertConfig.swift b/ProHUD/Alert/AlertConfig.swift
index f95a1cb..ef8be65 100644
--- a/ProHUD/Alert/AlertConfig.swift
+++ b/ProHUD/Alert/AlertConfig.swift
@@ -1,5 +1,5 @@
//
-// AlertConfig.swift
+// cfg.alert.swift
// ProHUD
//
// Created by xaoxuu on 2019/7/29.
@@ -30,8 +30,6 @@ public extension ProHUD.Configuration {
// MARK: 文本样式
/// 标题字体
public var titleFont = UIFont.boldSystemFont(ofSize: 22)
- /// 标题颜色
- public var titleColor = UIColorForPrimaryLabel
/// 标题最多行数
public var titleMaxLines = Int(1)
@@ -40,8 +38,6 @@ public extension ProHUD.Configuration {
/// 正文字体
public var bodyFont = UIFont.systemFont(ofSize: 17)
- /// 正文颜色
- public var bodyColor = UIColorForSecondaryLabel
/// 正文最多行数
public var bodyMaxLines = Int(5)
@@ -49,240 +45,257 @@ public extension ProHUD.Configuration {
/// 按钮字体
public var buttonFont = UIFont.boldSystemFont(ofSize: 18)
- // MARK: 逻辑
- /// 多少秒后显示强制退出的按钮(只有无按钮的弹窗才会出现)
- public var minimizeTimeout = TimeInterval(10)
- /// 最小化按钮标题
- public var minimizeTitle = String("隐藏窗口")
-
// MARK: 生命周期
+
/// 加载视图
- lazy var loadSubviews: (ProHUD.Alert, Alert) -> Void = {
- return { (vc, config) in
- debugPrint(vc, "loadSubviews")
- if vc.contentView.superview == nil {
- vc.view.addSubview(vc.contentView)
- vc.contentView.contentView.addSubview(vc.contentStack)
-
- vc.contentStack.spacing = alertConfig.margin + alertConfig.padding
-
- vc.contentView.layer.masksToBounds = true
- vc.contentView.layer.cornerRadius = alertConfig.cornerRadius
-
- vc.contentView.snp.makeConstraints { (mk) in
- mk.center.equalToSuperview()
- mk.width.lessThanOrEqualTo(CGFloat.minimum(UIScreen.main.bounds.width * 0.68, alertConfig.maxWidth))
- }
- vc.contentStack.snp.makeConstraints { (mk) in
- mk.centerX.equalToSuperview()
- mk.top.equalToSuperview().offset(alertConfig.padding)
- mk.bottom.equalToSuperview().offset(-alertConfig.padding)
- mk.leading.equalToSuperview().offset(alertConfig.padding)
- mk.trailing.equalToSuperview().offset(-alertConfig.padding)
- }
- }
-
- }
- }()
+ /// - Parameter callback: 回调代码
+ public mutating func loadSubviews(_ callback: @escaping (ProHUD.Alert) -> Void) {
+ privLoadSubviews = callback
+ }
/// 更新视图
- lazy var updateFrame: (ProHUD.Alert, Alert) -> Void = {
- return { (vc, config) in
- debugPrint(vc, "updateFrame")
- let isFirstLayout: Bool
- // 图标和文字至少有一个,如果都没有添加到视图中,说明是第一次layout
- if vc.textStack.superview == nil && vc.imageView?.superview == nil {
- isFirstLayout = true
- } else {
- isFirstLayout = false
- }
- let imgStr: String
- switch vc.vm.scene {
- case .success:
- imgStr = "ProHUDSuccess"
- case .warning:
- imgStr = "ProHUDWarning"
- case .error:
- imgStr = "ProHUDError"
- case .loading:
- imgStr = "ProHUDLoading"
- case .confirm:
- imgStr = "ProHUDMessage"
- case .delete:
- imgStr = "ProHUDTrash"
- default:
- imgStr = "ProHUDMessage"
- }
- let img = vc.vm.icon ?? ProHUD.image(named: imgStr)
- if let imgv = vc.imageView {
- imgv.image = img
- } else {
- let icon = UIImageView(image: img)
- vc.contentStack.addArrangedSubview(icon)
- icon.snp.makeConstraints { (mk) in
- mk.top.greaterThanOrEqualTo(vc.contentView).offset(config.padding*2.25)
- mk.bottom.lessThanOrEqualTo(vc.contentView).offset(-config.padding*2.25)
- mk.leading.greaterThanOrEqualTo(vc.contentView).offset(config.padding*4)
- mk.trailing.lessThanOrEqualTo(vc.contentView).offset(-config.padding*4)
- }
- vc.imageView = icon
- }
-
- // text
- if vc.vm.title?.count ?? 0 > 0 || vc.vm.message?.count ?? 0 > 0 {
- vc.contentStack.addArrangedSubview(vc.textStack)
- vc.textStack.snp.makeConstraints { (mk) in
- mk.top.greaterThanOrEqualTo(vc.contentView).offset(config.padding*1.75)
- mk.bottom.lessThanOrEqualTo(vc.contentView).offset(-config.padding*1.75)
- mk.leading.greaterThanOrEqualTo(vc.contentView).offset(config.padding*2)
- mk.trailing.lessThanOrEqualTo(vc.contentView).offset(-config.padding*2)
- }
- if vc.vm.title?.count ?? 0 > 0 {
- if let lb = vc.titleLabel {
- lb.text = vc.vm.title
- } else {
- let title = UILabel()
- title.textAlignment = .center
- title.numberOfLines = config.titleMaxLines
- title.textColor = config.titleColor
- title.text = vc.vm.title
- vc.textStack.addArrangedSubview(title)
- vc.titleLabel = title
- }
- if vc.vm.message?.count ?? 0 > 0 {
- // 有message
- vc.titleLabel?.font = config.titleFont
- } else {
- // 没有message
- vc.titleLabel?.font = config.boldTextFont
- }
- } else {
- vc.titleLabel?.removeFromSuperview()
- }
- if vc.vm.message?.count ?? 0 > 0 {
- if let lb = vc.messageLabel {
- lb.text = vc.vm.message
- } else {
- let body = UILabel()
- body.textAlignment = .center
- body.font = config.bodyFont
- body.numberOfLines = config.bodyMaxLines
- body.textColor = config.bodyColor
- body.text = vc.vm.message
- vc.textStack.addArrangedSubview(body)
- vc.messageLabel = body
- }
- if vc.vm.title?.count ?? 0 > 0 {
- // 有title
- vc.messageLabel?.font = config.bodyFont
- } else {
- // 没有title
- vc.messageLabel?.font = config.boldTextFont
- }
- } else {
- vc.messageLabel?.removeFromSuperview()
- }
- } else {
- vc.textStack.removeFromSuperview()
- }
- if vc.actionStack.superview != nil {
- if isFirstLayout {
- vc.contentStack.addArrangedSubview(vc.actionStack)
- } else {
- vc.actionStack.transform = .init(scaleX: 1, y: 0.001)
- UIView.animateForAlert {
- vc.contentStack.addArrangedSubview(vc.actionStack)
- vc.view.layoutIfNeeded()
- }
- }
- // 适配横竖屏和iPad
- if isPortrait == false {
- vc.actionStack.axis = .horizontal
- vc.actionStack.alignment = .fill
- vc.actionStack.distribution = .fillEqually
- }
- vc.actionStack.snp.makeConstraints { (mk) in
- mk.width.greaterThanOrEqualTo(200)
- mk.leading.trailing.equalToSuperview()
- }
- if isFirstLayout == false {
- UIView.animateForAlert {
- vc.actionStack.transform = .identity
- }
- }
-
- }
-
- if isFirstLayout {
- vc.view.layoutIfNeeded()
- vc.imageView?.transform = .init(scaleX: 0.75, y: 0.75)
- UIView.animateForAlert {
- vc.imageView?.transform = .identity
- vc.view.layoutIfNeeded()
- }
- } else {
- UIView.animateForAlert {
- vc.view.layoutIfNeeded()
- }
- }
- }
- }()
+ /// - Parameter callback: 回调代码
+ public mutating func reloadData(_ callback: @escaping (ProHUD.Alert) -> Void) {
+ privReloadData = callback
+ }
- /// 加载强制按钮
- lazy var showNavButtons: (ProHUD.Alert, Alert) -> Void = {
- return { (vc, config) in
- debugPrint(vc, "showNavButtons")
- let btn = ProHUD.Alert.Button.minimizeButton()
- let bg = ProHUD.BlurView()
- bg.layer.masksToBounds = true
- bg.layer.cornerRadius = config.cornerRadius
- if let last = vc.view.subviews.last {
- vc.view.insertSubview(bg, belowSubview: last)
+ /// 多少秒后显示强制退出的按钮(只有无按钮的弹窗才会出现)
+ public var forceQuitTimer = TimeInterval(10)
+
+ /// 强制退出按钮标题
+ public var forceQuitTitle = "隐藏窗口"
+
+ /// 加载强制退出按钮
+ /// - Parameter callback: 回调代码
+ public mutating func loadForceQuitButton(_ callback: @escaping (ProHUD.Alert) -> Void) {
+ privLoadForceQuitButton = callback
+ }
+
+ }
+}
+
+
+// MARK: - 默认实现
+
+internal extension ProHUD.Configuration.Alert {
+ var loadSubviews: (ProHUD.Alert) -> Void {
+ return privLoadSubviews
+ }
+
+ var reloadData: (ProHUD.Alert) -> Void {
+ return privReloadData
+ }
+
+ var loadForceQuitButton: (ProHUD.Alert) -> Void {
+ return privLoadForceQuitButton
+ }
+}
+
+fileprivate var privLoadSubviews: (ProHUD.Alert) -> Void = {
+ return { (vc) in
+ debug(vc, "loadSubviews")
+ let config = cfg.alert
+ if vc.contentView.superview == nil {
+ vc.view.addSubview(vc.contentView)
+ vc.contentView.contentView.addSubview(vc.contentStack)
+
+ vc.contentStack.spacing = cfg.alert.margin + cfg.alert.padding
+
+ vc.contentView.layer.masksToBounds = true
+ vc.contentView.layer.cornerRadius = cfg.alert.cornerRadius
+
+ vc.contentView.snp.makeConstraints { (mk) in
+ mk.center.equalToSuperview()
+ mk.width.lessThanOrEqualTo(CGFloat.minimum(UIScreen.main.bounds.width * 0.68, cfg.alert.maxWidth))
+ }
+ vc.contentStack.snp.makeConstraints { (mk) in
+ mk.centerX.equalToSuperview()
+ mk.top.equalToSuperview().offset(cfg.alert.padding)
+ mk.bottom.equalToSuperview().offset(-cfg.alert.padding)
+ mk.leading.equalToSuperview().offset(cfg.alert.padding)
+ mk.trailing.equalToSuperview().offset(-cfg.alert.padding)
+ }
+ }
+
+ }
+}()
+
+fileprivate var privReloadData: (ProHUD.Alert) -> Void = {
+ return { (vc) in
+ debug(vc, "reloadData")
+ let config = cfg.alert
+ let isFirstLayout: Bool
+ // 图标和文字至少有一个,如果都没有添加到视图中,说明是第一次layout
+ if vc.textStack.superview == nil && vc.imageView?.superview == nil {
+ isFirstLayout = true
+ } else {
+ isFirstLayout = false
+ }
+ let imgStr: String
+ switch vc.vm.scene {
+ case .success:
+ imgStr = "ProHUDSuccess"
+ case .warning:
+ imgStr = "ProHUDWarning"
+ case .error:
+ imgStr = "ProHUDError"
+ case .loading:
+ imgStr = "ProHUDLoading"
+ case .confirm:
+ imgStr = "ProHUDMessage"
+ case .delete:
+ imgStr = "ProHUDTrash"
+ default:
+ imgStr = "ProHUDMessage"
+ }
+ let img = vc.vm.icon ?? ProHUD.image(named: imgStr)
+ if let imgv = vc.imageView {
+ imgv.image = img
+ } else {
+ let icon = UIImageView(image: img)
+ vc.contentStack.addArrangedSubview(icon)
+ icon.snp.makeConstraints { (mk) in
+ mk.top.greaterThanOrEqualTo(vc.contentView).offset(config.padding*2.25)
+ mk.bottom.lessThanOrEqualTo(vc.contentView).offset(-config.padding*2.25)
+ mk.leading.greaterThanOrEqualTo(vc.contentView).offset(config.padding*4)
+ mk.trailing.lessThanOrEqualTo(vc.contentView).offset(-config.padding*4)
+ }
+ vc.imageView = icon
+ }
+
+ // text
+ if vc.vm.title?.count ?? 0 > 0 || vc.vm.message?.count ?? 0 > 0 {
+ vc.contentStack.addArrangedSubview(vc.textStack)
+ vc.textStack.snp.makeConstraints { (mk) in
+ mk.top.greaterThanOrEqualTo(vc.contentView).offset(config.padding*1.75)
+ mk.bottom.lessThanOrEqualTo(vc.contentView).offset(-config.padding*1.75)
+ mk.leading.greaterThanOrEqualTo(vc.contentView).offset(config.padding*2)
+ mk.trailing.lessThanOrEqualTo(vc.contentView).offset(-config.padding*2)
+ }
+ if vc.vm.title?.count ?? 0 > 0 {
+ if let lb = vc.titleLabel {
+ lb.text = vc.vm.title
} else {
- vc.view.addSubview(bg)
+ let title = UILabel()
+ title.textAlignment = .center
+ title.numberOfLines = config.titleMaxLines
+ title.textColor = cfg.primaryLabelColor
+ title.text = vc.vm.title
+ vc.textStack.addArrangedSubview(title)
+ vc.titleLabel = title
}
- bg.snp.makeConstraints { (mk) in
- mk.leading.trailing.equalTo(vc.contentView)
- mk.top.equalTo(vc.contentView.snp.bottom).offset(config.margin)
+ if vc.vm.message?.count ?? 0 > 0 {
+ // 有message
+ vc.titleLabel?.font = config.titleFont
+ } else {
+ // 没有message
+ vc.titleLabel?.font = config.boldTextFont
}
- bg.contentView.addSubview(btn)
- btn.snp.makeConstraints { (mk) in
- mk.edges.equalToSuperview()
+ } else {
+ vc.titleLabel?.removeFromSuperview()
+ }
+ if vc.vm.message?.count ?? 0 > 0 {
+ if let lb = vc.messageLabel {
+ lb.text = vc.vm.message
+ } else {
+ let body = UILabel()
+ body.textAlignment = .center
+ body.font = config.bodyFont
+ body.numberOfLines = config.bodyMaxLines
+ body.textColor = cfg.secondaryLabelColor
+ body.text = vc.vm.message
+ vc.textStack.addArrangedSubview(body)
+ vc.messageLabel = body
}
- bg.alpha = 0
- bg.layoutIfNeeded()
- bg.transform = .init(translationX: 0, y: -2*(config.margin+bg.frame.size.height))
+ if vc.vm.title?.count ?? 0 > 0 {
+ // 有title
+ vc.messageLabel?.font = config.bodyFont
+ } else {
+ // 没有title
+ vc.messageLabel?.font = config.boldTextFont
+ }
+ } else {
+ vc.messageLabel?.removeFromSuperview()
+ }
+ } else {
+ vc.textStack.removeFromSuperview()
+ }
+ if vc.actionStack.superview != nil {
+ if isFirstLayout {
+ vc.contentStack.addArrangedSubview(vc.actionStack)
+ } else {
+ vc.actionStack.transform = .init(scaleX: 1, y: 0.001)
UIView.animateForAlert {
- bg.alpha = 1
- bg.transform = .identity
- }
- vc.addTouchUpAction(for: btn) { [weak vc] in
- debugPrint("点击了隐藏")
- vc?.minimizeCallback?()
- vc?.remove()
+ vc.contentStack.addArrangedSubview(vc.actionStack)
+ vc.view.layoutIfNeeded()
}
}
- }()
-
- /// 加载视图
- /// - Parameter callback: 回调代码
- public mutating func loadSubviews(_ callback: @escaping (ProHUD.Alert, Alert) -> Void) {
- loadSubviews = callback
+ // 适配横竖屏和iPad
+ if isPortrait == false {
+ vc.actionStack.axis = .horizontal
+ vc.actionStack.alignment = .fill
+ vc.actionStack.distribution = .fillEqually
+ }
+ vc.actionStack.snp.makeConstraints { (mk) in
+ mk.width.greaterThanOrEqualTo(200)
+ mk.leading.trailing.equalToSuperview()
+ }
+ if isFirstLayout == false {
+ UIView.animateForAlert {
+ vc.actionStack.transform = .identity
+ }
+ }
+
}
- /// 更新视图
- /// - Parameter callback: 回调代码
- public mutating func updateFrame(_ callback: @escaping (ProHUD.Alert, Alert) -> Void) {
- updateFrame = callback
+ if isFirstLayout {
+ vc.view.layoutIfNeeded()
+ vc.imageView?.transform = .init(scaleX: 0.75, y: 0.75)
+ UIView.animateForAlert {
+ vc.imageView?.transform = .identity
+ vc.view.layoutIfNeeded()
+ }
+ } else {
+ UIView.animateForAlert {
+ vc.view.layoutIfNeeded()
+ }
}
-
}
-}
+}()
-internal var alertConfig = ProHUD.Configuration.Alert()
-
-public extension ProHUD {
- static func configAlert(_ config: (inout Configuration.Alert) -> Void) {
- config(&alertConfig)
+fileprivate var privLoadForceQuitButton: (ProHUD.Alert) -> Void = {
+ return { (vc) in
+ debug(vc, "showNavButtons")
+ let config = cfg.alert
+ let btn = ProHUD.Alert.Button.forceQuitButton()
+ btn.setTitle(cfg.alert.forceQuitTitle, for: .normal)
+ let bg = ProHUD.BlurView()
+ bg.layer.masksToBounds = true
+ bg.layer.cornerRadius = config.cornerRadius
+ if let last = vc.view.subviews.last {
+ vc.view.insertSubview(bg, belowSubview: last)
+ } else {
+ vc.view.addSubview(bg)
+ }
+ bg.snp.makeConstraints { (mk) in
+ mk.leading.trailing.equalTo(vc.contentView)
+ mk.top.equalTo(vc.contentView.snp.bottom).offset(config.margin)
+ }
+ bg.contentView.addSubview(btn)
+ btn.snp.makeConstraints { (mk) in
+ mk.edges.equalToSuperview()
+ }
+ bg.alpha = 0
+ bg.layoutIfNeeded()
+ bg.transform = .init(translationX: 0, y: -2*(config.margin+bg.frame.size.height))
+ UIView.animateForAlert {
+ bg.alpha = 1
+ bg.transform = .identity
+ }
+ vc.addTouchUpAction(for: btn) { [weak vc] in
+ debug("点击了隐藏")
+ vc?.minimizeCallback?()
+ vc?.remove()
+ }
}
-}
+}()
diff --git a/ProHUD/Alert/AlertController.swift b/ProHUD/Alert/AlertController.swift
index 3f130d1..2a42ac5 100644
--- a/ProHUD/Alert/AlertController.swift
+++ b/ProHUD/Alert/AlertController.swift
@@ -18,14 +18,14 @@ public extension ProHUD {
/// 正文(包括icon、textStack、actionStack)
internal var contentStack: StackContainer = {
let stack = StackContainer()
- stack.spacing = alertConfig.margin
+ stack.spacing = cfg.alert.margin
return stack
}()
/// 文本区域
internal var textStack: StackContainer = {
let stack = StackContainer()
- stack.spacing = alertConfig.margin
+ stack.spacing = cfg.alert.margin
return stack
}()
internal var imageView: UIImageView?
@@ -35,7 +35,7 @@ public extension ProHUD {
internal var actionStack: StackContainer = {
let stack = StackContainer()
stack.alignment = .fill
- stack.spacing = alertConfig.margin
+ stack.spacing = cfg.alert.margin
return stack
}()
@@ -56,7 +56,7 @@ public extension ProHUD {
/// - Parameter icon: 图标
public convenience init(scene: Scene = .default, title: String? = nil, message: String? = nil, icon: UIImage? = nil) {
self.init()
- view.tintColor = alertConfig.tintColor
+ view.tintColor = cfg.alert.tintColor
vm.scene = scene
vm.title = title
vm.message = message
@@ -151,7 +151,7 @@ public extension ProHUD {
vm.message = message
vm.scene = scene
vm.icon = icon
- alertConfig.updateFrame(self, alertConfig)
+ cfg.alert.reloadData(self)
return self
}
@@ -217,8 +217,8 @@ fileprivate extension ProHUD.Alert {
willLayout = DispatchWorkItem(block: { [weak self] in
if let a = self {
// 布局
- alertConfig.loadSubviews(a, alertConfig)
- alertConfig.updateFrame(a, alertConfig)
+ cfg.alert.loadSubviews(a)
+ cfg.alert.reloadData(a)
// 超时
if let t = a.timeout, t > 0 {
a.timeoutBlock = DispatchWorkItem(block: { [weak self] in
@@ -229,13 +229,13 @@ fileprivate extension ProHUD.Alert {
a.timeoutBlock = nil
}
// 顶部按钮
- if alertConfig.minimizeTimeout > 0 && self?.actionStack.superview == nil {
+ if cfg.alert.forceQuitTimer > 0 && self?.actionStack.superview == nil {
a.showNavButtonsBlock = DispatchWorkItem(block: { [weak self] in
if let s = self {
- alertConfig.showNavButtons(s, alertConfig)
+ cfg.alert.loadForceQuitButton(s)
}
})
- DispatchQueue.main.asyncAfter(deadline: .now()+alertConfig.minimizeTimeout, execute: a.showNavButtonsBlock!)
+ DispatchQueue.main.asyncAfter(deadline: .now()+cfg.alert.forceQuitTimer, execute: a.showNavButtonsBlock!)
}
}
})
@@ -394,7 +394,7 @@ fileprivate extension ProHUD {
} else if alerts.count == 1 {
alerts.removeAll()
} else {
- debugPrint("漏洞:已经没有alert了")
+ debug("漏洞:已经没有alert了")
}
}
diff --git a/ProHUD/Alert/AlertView.swift b/ProHUD/Alert/AlertView.swift
index 8521f4b..683e82b 100644
--- a/ProHUD/Alert/AlertView.swift
+++ b/ProHUD/Alert/AlertView.swift
@@ -13,15 +13,15 @@ internal extension ProHUD.Alert {
class func actionButton(title: String?) -> UIButton {
let btn = Button(type: .system)
btn.setTitle(title, for: .normal)
- btn.layer.cornerRadius = alertConfig.cornerRadius / 2
- btn.titleLabel?.font = alertConfig.buttonFont
+ btn.layer.cornerRadius = cfg.alert.cornerRadius / 2
+ btn.titleLabel?.font = cfg.alert.buttonFont
return btn
}
func update(style: UIAlertAction.Style) {
let pd = CGFloat(8)
if style != .cancel {
- backgroundColor = dynamicColor.withAlphaComponent(0.04)
+ backgroundColor = cfg.dynamicColor.withAlphaComponent(0.04)
contentEdgeInsets = .init(top: pd*1.5, left: pd*1.5, bottom: pd*1.5, right: pd*1.5)
} else {
contentEdgeInsets = .init(top: pd*0.5, left: pd*1.5, bottom: pd*0.5, right: pd*1.5)
@@ -32,21 +32,20 @@ internal extension ProHUD.Alert {
case .destructive:
setTitleColor(.init(red: 244/255, green: 67/255, blue: 54/255, alpha: 1), for: .normal)
case .cancel:
- setTitleColor(UIColorForSecondaryLabel, for: .normal)
+ setTitleColor(cfg.secondaryLabelColor, for: .normal)
@unknown default:
break
}
tag = style.rawValue
}
- class func minimizeButton() -> UIButton {
+ class func forceQuitButton() -> UIButton {
let btn = Button(type: .system)
- let pd = alertConfig.padding/2
+ let pd = cfg.alert.padding/2
btn.contentEdgeInsets = .init(top: pd*1.5, left: pd*1.5, bottom: pd*1.5, right: pd*1.5)
btn.imageEdgeInsets.right = pd*1.5
- btn.setTitle(alertConfig.minimizeTitle, for: .normal)
btn.setTitleColor(UIColor(red:1.00, green:0.55, blue:0.21, alpha:1.00), for: .normal)
- btn.titleLabel?.font = alertConfig.buttonFont
+ btn.titleLabel?.font = cfg.alert.buttonFont
return btn
}
diff --git a/ProHUD/Guard/GuardConfig.swift b/ProHUD/Guard/GuardConfig.swift
index 72e5b19..bfbe1d3 100644
--- a/ProHUD/Guard/GuardConfig.swift
+++ b/ProHUD/Guard/GuardConfig.swift
@@ -1,5 +1,5 @@
//
-// GuardConfig.swift
+// cfg.guard.swift
// ProHUD
//
// Created by xaoxuu on 2019/7/31.
@@ -29,13 +29,9 @@ public extension ProHUD.Configuration {
// MARK: 文本样式
/// 标题字体
public var titleFont = UIFont.boldSystemFont(ofSize: 22)
- /// 标题颜色
- public var titleColor = UIColorForPrimaryLabel
/// 正文字体
public var bodyFont = UIFont.systemFont(ofSize: 18)
- /// 正文颜色
- public var bodyColor = UIColorForSecondaryLabel
// MARK: 按钮样式
/// 按钮字体
@@ -45,111 +41,89 @@ public extension ProHUD.Configuration {
/// 按钮圆角半径
public var buttonCornerRadius = CGFloat(12)
- lazy var loadTitleLabel: (ProHUD.Guard, Guard) -> Void = {
- return { (vc, config) in
- debugPrint(vc, "loadTitleLabel")
- if vc.titleLabel == nil {
- vc.titleLabel = UILabel()
- vc.titleLabel?.font = config.titleFont
- vc.titleLabel?.textColor = config.titleColor
- vc.titleLabel?.numberOfLines = 0
- vc.titleLabel?.textAlignment = .justified
- }
- }
- }()
-
- lazy var loadBodyLabel: (ProHUD.Guard, Guard) -> Void = {
- return { (vc, config) in
- debugPrint(vc, "loadBodyLabel")
- if vc.bodyLabel == nil {
- vc.bodyLabel = UILabel()
- vc.bodyLabel?.font = config.bodyFont
- vc.bodyLabel?.textColor = config.bodyColor
- vc.bodyLabel?.numberOfLines = 0
- vc.titleLabel?.textAlignment = .justified
- }
- }
- }()
-
/// 加载视图
- lazy var loadSubviews: (ProHUD.Guard, Guard) -> Void = {
- return { (vc, config) in
- debugPrint(vc, "loadSubviews")
- // background
- vc.view.tintColor = config.tintColor
- vc.view.backgroundColor = UIColor(white: 0, alpha: 0)
- vc.view.addSubview(vc.contentView)
- var width = UIScreen.main.bounds.width
- if width > config.cardMaxWidth {
- // 横屏或者iPad
- width = config.cardMaxWidth
- vc.contentView.layer.masksToBounds = true
- vc.contentView.layer.cornerRadius = config.cardCornerRadius
+ /// - Parameter callback: 回调代码
+ public mutating func loadSubviews(_ callback: @escaping (ProHUD.Guard) -> Void) {
+ privLoadSubviews = callback
+ }
+
+ /// 更新视图
+ /// - Parameter callback: 回调代码
+ public mutating func reloadData(_ callback: @escaping (ProHUD.Guard) -> Void) {
+ privReloadData = callback
+ }
+
+ }
+}
+
+// MARK: - 默认实现
+
+internal extension ProHUD.Configuration.Guard {
+ var loadSubviews: (ProHUD.Guard) -> Void {
+ return privLoadSubviews
+ }
+ var reloadData: (ProHUD.Guard) -> Void {
+ return privReloadData
+ }
+}
+
+fileprivate var privLoadSubviews: (ProHUD.Guard) -> Void = {
+ return { (vc) in
+ debug(vc, "loadSubviews")
+ let config = cfg.guard
+ // background
+ vc.view.tintColor = config.tintColor
+ vc.view.backgroundColor = UIColor(white: 0, alpha: 0)
+ vc.view.addSubview(vc.contentView)
+ vc.contentView.contentView.addSubview(vc.contentStack)
+ vc.contentStack.addArrangedSubview(vc.textStack)
+ vc.contentStack.addArrangedSubview(vc.actionStack)
+ }
+}()
+
+fileprivate var privReloadData: (ProHUD.Guard) -> Void = {
+ return { (vc) in
+ debug(vc, "reloadData")
+ let config = cfg.guard
+ // 更新布局
+ var width = UIScreen.main.bounds.width
+ if width > config.cardMaxWidth {
+ // 横屏或者iPad
+ width = config.cardMaxWidth
+ vc.contentView.layer.masksToBounds = true
+ vc.contentView.layer.cornerRadius = config.cardCornerRadius
+ } else {
+ vc.contentView.layer.shadowRadius = 4
+ vc.contentView.layer.shadowOffset = .init(width: 0, height: 2)
+ vc.contentView.layer.shadowOpacity = 0.12
+ }
+ vc.contentView.snp.makeConstraints { (mk) in
+ mk.centerX.equalToSuperview()
+ if UIDevice.current.userInterfaceIdiom == .phone {
+ if width == config.cardMaxWidth {
+ mk.bottom.equalToSuperview().offset(-Inspire.shared.screen.safeAreaInsets.bottom)
} else {
- vc.contentView.layer.shadowRadius = 4
- vc.contentView.layer.shadowOffset = .init(width: 0, height: 2)
- vc.contentView.layer.shadowOpacity = 0.12
+ mk.bottom.equalToSuperview()
}
- vc.contentView.snp.makeConstraints { (mk) in
- mk.centerX.equalToSuperview()
- if UIDevice.current.userInterfaceIdiom == .phone {
- if width == config.cardMaxWidth {
- mk.bottom.equalToSuperview().offset(-Inspire.shared.screen.safeAreaInsets.bottom)
- } else {
- mk.bottom.equalToSuperview()
- }
- } else if UIDevice.current.userInterfaceIdiom == .pad {
- mk.centerY.equalToSuperview()
- }
- mk.width.equalTo(width)
- }
- // stack
- vc.contentView.contentView.addSubview(vc.contentStack)
- vc.contentStack.snp.makeConstraints { (mk) in
- mk.top.equalToSuperview().offset(config.padding + config.margin)
- mk.centerX.equalToSuperview()
- if width == config.cardMaxWidth {
- mk.bottom.equalToSuperview().offset(-config.padding)
- } else {
- mk.bottom.equalToSuperview().offset(-config.margin-Inspire.shared.screen.safeAreaInsets.bottom)
- }
- if isPortrait {
- mk.width.equalToSuperview().offset(-config.padding * 2)
- } else {
- mk.width.equalToSuperview().offset(-config.padding * 4)
- }
- }
- vc.contentStack.addArrangedSubview(vc.textStack)
-
+ } else if UIDevice.current.userInterfaceIdiom == .pad {
+ mk.centerY.equalToSuperview()
}
- }()
-
- /// 更新视图
- lazy var updateFrame: (ProHUD.Guard, Guard) -> Void = {
- return { (vc, config) in
- debugPrint(vc, "updateFrame")
+ mk.width.equalTo(width)
+ }
+ // stack
+ vc.contentStack.snp.makeConstraints { (mk) in
+ mk.top.equalToSuperview().offset(config.padding + config.margin)
+ mk.centerX.equalToSuperview()
+ if width == config.cardMaxWidth {
+ mk.bottom.equalToSuperview().offset(-config.padding)
+ } else {
+ mk.bottom.equalToSuperview().offset(-config.margin-Inspire.shared.screen.safeAreaInsets.bottom)
+ }
+ if isPortrait {
+ mk.width.equalToSuperview().offset(-config.padding * 2)
+ } else {
+ mk.width.equalToSuperview().offset(-config.padding * 4)
}
- }()
-
- /// 加载视图
- /// - Parameter callback: 回调代码
- public mutating func loadSubviews(_ callback: @escaping (ProHUD.Guard, Guard) -> Void) {
- loadSubviews = callback
}
-
- /// 更新视图
- /// - Parameter callback: 回调代码
- public mutating func updateFrame(_ callback: @escaping (ProHUD.Guard, Guard) -> Void) {
- updateFrame = callback
- }
-
}
-}
-
-internal var guardConfig = ProHUD.Configuration.Guard()
-
-public extension ProHUD {
- static func configGuard(_ config: (inout Configuration.Guard) -> Void) {
- config(&guardConfig)
- }
-}
+}()
diff --git a/ProHUD/Guard/GuardController.swift b/ProHUD/Guard/GuardController.swift
index 7e3092e..aa1ab21 100644
--- a/ProHUD/Guard/GuardController.swift
+++ b/ProHUD/Guard/GuardController.swift
@@ -17,7 +17,7 @@ public extension ProHUD {
/// 内容容器(包括textStack、actionStack)
public var contentStack: StackContainer = {
let stack = StackContainer()
- stack.spacing = guardConfig.padding + guardConfig.margin
+ stack.spacing = cfg.guard.padding + cfg.guard.margin
stack.alignment = .fill
return stack
}()
@@ -25,19 +25,19 @@ public extension ProHUD {
/// 文本区域
public var textStack: StackContainer = {
let stack = StackContainer()
- stack.spacing = guardConfig.margin
+ stack.spacing = cfg.guard.margin
stack.alignment = .fill
return stack
}()
- public var titleLabel: UILabel?
- public var bodyLabel: UILabel?
+// public var titleLabel: UILabel?
+// public var bodyLabel: UILabel?
/// 操作区域
public var actionStack: StackContainer = {
let stack = StackContainer()
stack.alignment = .fill
- stack.spacing = guardConfig.margin
+ stack.spacing = cfg.guard.margin
return stack
}()
@@ -57,15 +57,15 @@ public extension ProHUD {
public convenience init(title: String? = nil, message: String? = nil) {
self.init()
view = View()
- view.tintColor = guardConfig.tintColor
+ view.tintColor = cfg.guard.tintColor
if let _ = title {
loadTitle(title)
}
if let _ = message {
loadBody(message)
}
- guardConfig.loadSubviews(self, guardConfig)
-// willLayoutSubviews()
+ cfg.guard.loadSubviews(self)
+ cfg.guard.reloadData(self)
// 点击
let tap = UITapGestureRecognizer(target: self, action: #selector(privDidTapped(_:)))
@@ -81,7 +81,7 @@ public extension ProHUD {
}
deinit {
- debugPrint(self, "deinit")
+ debug(self, "deinit")
}
public func push(to viewController: UIViewController? = nil) {
@@ -106,7 +106,7 @@ public extension ProHUD {
public func pop() {
if displaying {
- debugPrint("pop")
+ debug("pop")
displaying = false
view.isUserInteractionEnabled = false
self.removeFromParent()
@@ -126,21 +126,31 @@ public extension ProHUD.Guard {
@discardableResult
func loadTitle(_ text: String?) -> UILabel {
- guardConfig.loadTitleLabel(self, guardConfig)
- let lb = titleLabel!
+ let lb = UILabel()
+ lb.font = cfg.guard.titleFont
+ lb.textColor = cfg.primaryLabelColor
+ lb.numberOfLines = 0
+ lb.textAlignment = .justified
lb.text = text
- if textStack.arrangedSubviews.count > 0 {
- textStack.insertArrangedSubview(lb, at: 0)
+ textStack.addArrangedSubview(lb)
+ if #available(iOS 11.0, *) {
+ let count = textStack.arrangedSubviews.count
+ if count > 1 {
+ textStack.setCustomSpacing(cfg.guard.margin * 2, after: textStack.arrangedSubviews[count-2])
+ }
} else {
- textStack.addArrangedSubview(lb)
+ // Fallback on earlier versions
}
return lb
}
@discardableResult
func loadBody(_ text: String?) -> UILabel {
- guardConfig.loadBodyLabel(self, guardConfig)
- let lb = bodyLabel!
+ let lb = UILabel()
+ lb.font = cfg.guard.bodyFont
+ lb.textColor = cfg.secondaryLabelColor
+ lb.numberOfLines = 0
+ lb.textAlignment = .justified
lb.text = text
textStack.addArrangedSubview(lb)
return lb
@@ -149,7 +159,7 @@ public extension ProHUD.Guard {
@discardableResult
func loadButton(style: UIAlertAction.Style, title: String?, action: (() -> Void)? = nil) -> UIButton {
let btn = Button.actionButton(title: title)
- btn.titleLabel?.font = guardConfig.buttonFont
+ btn.titleLabel?.font = cfg.guard.buttonFont
if actionStack.superview == nil {
contentStack.addArrangedSubview(actionStack)
}
@@ -189,7 +199,7 @@ fileprivate extension ProHUD.Guard {
func translateOut() {
view.backgroundColor = UIColor(white: 0, alpha: 0)
- contentView.transform = .init(translationX: 0, y: view.frame.size.height - contentView.frame.minY + guardConfig.margin)
+ contentView.transform = .init(translationX: 0, y: view.frame.size.height - contentView.frame.minY + cfg.guard.margin)
}
diff --git a/ProHUD/Guard/GuardView.swift b/ProHUD/Guard/GuardView.swift
index c01a46b..0a1566f 100644
--- a/ProHUD/Guard/GuardView.swift
+++ b/ProHUD/Guard/GuardView.swift
@@ -42,8 +42,8 @@ internal extension ProHUD.Guard {
class func actionButton(title: String?) -> Button {
let btn = Button(type: .system)
btn.setTitle(title, for: .normal)
- btn.layer.cornerRadius = guardConfig.buttonCornerRadius
- btn.titleLabel?.font = guardConfig.buttonFont
+ btn.layer.cornerRadius = cfg.guard.buttonCornerRadius
+ btn.titleLabel?.font = cfg.guard.buttonFont
return btn
}
@@ -62,7 +62,7 @@ internal extension ProHUD.Guard {
backgroundColor = .init(red: 244/255, green: 67/255, blue: 54/255, alpha: 1)
setTitleColor(.white, for: .normal)
case .cancel:
- setTitleColor(UIColorForSecondaryLabel, for: .normal)
+ setTitleColor(cfg.secondaryLabelColor, for: .normal)
@unknown default:
break
}
diff --git a/ProHUD/HUDConfig.swift b/ProHUD/HUDConfig.swift
index fa1a850..b1e7c1c 100644
--- a/ProHUD/HUDConfig.swift
+++ b/ProHUD/HUDConfig.swift
@@ -11,9 +11,40 @@ import UIKit
public extension ProHUD {
struct Configuration {
- internal var toast = Toast()
- internal var alert = Alert()
- internal var `guard` = Guard()
+ /// 是否允许Debug模式输出
+ public var enableDebugPrint = true
+
+ /// 动态颜色(适配iOS13)
+ public lazy var dynamicColor: UIColor = {
+ if #available(iOS 13.0, *) {
+ let color = UIColor { (traitCollection: UITraitCollection) -> UIColor in
+ if traitCollection.userInterfaceStyle == .dark {
+ return .white
+ } else {
+ return .black
+ }
+ }
+ return color
+ } else {
+ // Fallback on earlier versions
+ }
+ return .init(white: 0.2, alpha: 1)
+ }()
+
+ /// 主标签文本颜色
+ public lazy var primaryLabelColor: UIColor = {
+ return dynamicColor.withAlphaComponent(0.75)
+ }()
+
+ /// 次级标签文本颜色
+ public lazy var secondaryLabelColor: UIColor = {
+ return dynamicColor.withAlphaComponent(0.6)
+ }()
+
+
+ public var toast = Toast()
+ public var alert = Alert()
+ public var `guard` = Guard()
/// Toast的配置
/// - Parameter callback: 回调
@@ -36,3 +67,10 @@ public extension ProHUD {
}
}
+internal var cfg = ProHUD.Configuration()
+
+public extension ProHUD {
+ static func config(_ config: (inout Configuration) -> Void) {
+ config(&cfg)
+ }
+}
diff --git a/ProHUD/HUDController.swift b/ProHUD/HUDController.swift
index 925065b..1ad3c99 100644
--- a/ProHUD/HUDController.swift
+++ b/ProHUD/HUDController.swift
@@ -25,7 +25,7 @@ public class HUDController: UIViewController {
init() {
super.init(nibName: nil, bundle: nil)
- print(self, "init")
+ debug(self, "init")
}
required public init?(coder: NSCoder) {
@@ -33,7 +33,7 @@ public class HUDController: UIViewController {
}
deinit {
- debugPrint(self, "deinit")
+ debug(self, "deinit")
}
@@ -48,14 +48,6 @@ public class HUDController: UIViewController {
internal extension HUDController {
-// func animateOut(completion: ((Bool) -> Void)? = nil) {
-// UIView.animateForAlertBuildOut(animations: {
-// self.view.alpha = 0
-// }) { (done) in
-// completion?(done)
-// }
-// }
-
func addTouchUpAction(for button: UIButton, action: @escaping () -> Void) {
button.addTarget(self, action: #selector(didTappedButton(_:)), for: .touchUpInside)
buttonEvents[button] = action
diff --git a/ProHUD/HUDForGuard.swift b/ProHUD/HUDForGuard.swift
deleted file mode 100644
index 8e2c53a..0000000
--- a/ProHUD/HUDForGuard.swift
+++ /dev/null
@@ -1,73 +0,0 @@
-//
-// Guard.swift
-// ProHUD
-//
-// Created by xaoxuu on 2019/7/24.
-// Copyright © 2019 Titan Studio. All rights reserved.
-//
-
-import UIKit
-
-//public extension ProHUD {
-// class Guard: Element {
-//
-// public class View: UIView {
-// public var stack = UIStackView()
-//
-// public class Button: UIButton {
-//
-// }
-// }
-//
-//
-// public convenience init(title: String? = nil, message: String? = nil) {
-// self.init()
-// vm.title = title
-// vm.message = message
-// }
-//
-// public override func viewDidDisappear(_ animated: Bool) {
-// vm.disappearCallback?()
-// }
-//
-// }
-//
-//
-// @discardableResult
-// func show(_ guard: Guard) -> Guard {
-// return `guard`
-// }
-//
-// @discardableResult
-// func showGuard(title: String? = nil, message: String? = nil) -> Guard {
-// return ProHUD.shared.show(Guard(title: title, message: message))
-// }
-//
-// @discardableResult
-// class func showGuard(title: String? = nil, message: String? = nil) -> Guard {
-// return shared.showGuard(title: title, message: message)
-// }
-//
-//}
-//
-//public extension ProHUD.Guard {
-//
-// @discardableResult
-// func addAction(style: UIAlertAction.Style, title: String?, didTapped: ((View.Button) -> Void)?) -> ProHUD.Guard {
-//
-// return self
-// }
-//
-// @discardableResult
-// func addAction(custom: (View.Button) -> Void, didTapped: ((View.Button) -> Void)?) -> ProHUD.Guard {
-//
-// return self
-// }
-//
-// @discardableResult
-// func didDisappear(_ callback: (() -> Void)?) -> ProHUD.Guard {
-// vm.disappearCallback = callback
-// return self
-// }
-//
-//}
diff --git a/ProHUD/HUDForToast.swift b/ProHUD/HUDForToast.swift
deleted file mode 100644
index f02edc9..0000000
--- a/ProHUD/HUDForToast.swift
+++ /dev/null
@@ -1,61 +0,0 @@
-//
-// Toast.swift
-// ProHUD
-//
-// Created by xaoxuu on 2019/7/24.
-// Copyright © 2019 Titan Studio. All rights reserved.
-//
-
-import UIKit
-
-
-//public extension ProHUD {
-// class Toast: HUDController {
-//
-// public class View: UIView {
-// public var stack = UIStackView()
-//
-// public class Button: UIButton {
-//
-// }
-// }
-//
-// public convenience init(scene: HUDScene = .default, title: String?, message: String?, icon: UIImage?) {
-// self.init()
-// vm.scene = scene
-// vm.title = title
-// vm.message = message
-// vm.icon = icon
-// switch scene {
-// case .loading:
-// vm.timeout = nil
-// default:
-// vm.timeout = 2
-// }
-// }
-//
-// /// 设置超时时间
-// /// - Parameter timeout: 超时时间
-// public func timeout(_ timeout: TimeInterval?) -> Toast {
-// vm.timeout = timeout
-// return self
-// }
-//
-// }
-//
-// @discardableResult
-// func show(_ toast: Toast) -> Toast {
-// return toast
-// }
-//
-// @discardableResult
-// func showToast(scene: HUDScene = .default, title: String?, message: String?, icon: UIImage? = nil) -> Toast {
-// return ProHUD.shared.show(Toast(scene: scene, title: title, message: message, icon: icon))
-// }
-//
-// @discardableResult
-// class func showAlert(scene: HUDScene = .default, title: String?, message: String?, icon: UIImage? = nil) -> Toast {
-// return shared.showToast(scene: scene, title: title, message: message, icon: icon)
-// }
-//
-//}
diff --git a/ProHUD/HUDView.swift b/ProHUD/HUDView.swift
index dbdb20c..746c0a2 100644
--- a/ProHUD/HUDView.swift
+++ b/ProHUD/HUDView.swift
@@ -38,7 +38,7 @@ public extension ProHUD {
public override init(frame: CGRect) {
super.init(frame: frame)
- spacing = alertConfig.margin
+ spacing = cfg.alert.margin
distribution = .fill
alignment = .center
axis = .vertical
@@ -58,10 +58,8 @@ public extension ProHUD {
if #available(iOS 13.0, *) {
super.init(effect: UIBlurEffect(style: .systemMaterial))
-// backgroundColor = UIColor.init(white: 1, alpha: 0.3)
} else {
super.init(effect: UIBlurEffect(style: .extraLight))
- backgroundColor = UIColor.init(white: 1, alpha: 0.66)
}
}
diff --git a/ProHUD/ProHUD.swift b/ProHUD/ProHUD.swift
index ccc657f..bb18170 100644
--- a/ProHUD/ProHUD.swift
+++ b/ProHUD/ProHUD.swift
@@ -14,6 +14,10 @@ public class ProHUD {
public static let shared = ProHUD()
+ public var config: Configuration {
+ return cfg
+ }
+
internal var toasts = [Toast]()
internal var alerts = [Alert]()
@@ -22,9 +26,11 @@ public class ProHUD {
}
+// MARK: - Utilities
internal extension ProHUD {
+ /// 获取Bundle
static var bundle: Bundle {
var b = Bundle.init(for: ProHUD.Alert.self)
let p = b.path(forResource: "ProHUD", ofType: "bundle")
@@ -33,7 +39,7 @@ internal extension ProHUD {
}
return b
}
-
+ /// 获取Image
static func image(named: String) -> UIImage? {
return UIImage.init(named: named, in: bundle, compatibleWith: nil)
}
@@ -41,63 +47,26 @@ internal extension ProHUD {
}
+
+/// 是否是手机竖屏模式
internal var isPortrait: Bool {
- if UIScreen.main.bounds.width < 500 {
- return true
- } else {
- return false
- }
-}
-
-
-internal var dynamicColor: UIColor {
- if #available(iOS 13.0, *) {
- let color = UIColor { (traitCollection: UITraitCollection) -> UIColor in
- if traitCollection.userInterfaceStyle == .dark {
- return .white
- } else {
- return .black
- }
- }
- return color
- } else {
- // Fallback on earlier versions
- }
- return .init(white: 0.2, alpha: 1)
-}
-
-
-
-internal var UIColorForPrimaryLabel: UIColor {
- return dynamicColor.withAlphaComponent(0.75)
-}
-internal var UIColorForSecondaryLabel: UIColor {
- return dynamicColor.withAlphaComponent(0.6)
-}
-
-internal extension UIColor {
-
- var dynamicColor: UIColor {
- if #available(iOS 13.0, *) {
- let color = UIColor { (traitCollection: UITraitCollection) -> UIColor in
- if traitCollection.userInterfaceStyle == .dark {
- return .white
- } else {
- return .black
- }
- }
- return color
+ if UIDevice.current.userInterfaceIdiom == .phone {
+ if UIApplication.shared.statusBarOrientation.isPortrait {
+ debug("当前是手机竖屏模式")
+ return true
} else {
- // Fallback on earlier versions
+ debug("当前是手机横屏模式")
}
- return .init(white: 0.2, alpha: 1)
+ } else {
+ debug("非手机设备(unspecified、iPad、tv、carPlay)")
}
-
- var dynamicPrimaryLabelColor: UIColor {
- return dynamicColor.withAlphaComponent(0.75)
- }
- var dynamicSecondaryLabelColor: UIColor {
- return dynamicColor.withAlphaComponent(0.6)
- }
-
+ return false
}
+
+/// 可控Debug输出
+internal func debug(_ items: Any..., separator: String = " ", terminator: String = "\n") {
+ if cfg.enableDebugPrint {
+ debugPrint(items, separator: separator, terminator: terminator)
+ }
+}
+
diff --git a/ProHUD/Toast/ToastConfig.swift b/ProHUD/Toast/ToastConfig.swift
index 41f62c9..32e2078 100644
--- a/ProHUD/Toast/ToastConfig.swift
+++ b/ProHUD/Toast/ToastConfig.swift
@@ -1,5 +1,5 @@
//
-// ToastConfig.swift
+// cfg.toast.swift
// ProHUD
//
// Created by xaoxuu on 2019/7/31.
@@ -10,116 +10,118 @@ import SnapKit
public extension ProHUD.Configuration {
struct Toast {
+ // MARK: 卡片样式
/// 最大宽度(用于优化横屏或者iPad显示)
public var maxWidth = CGFloat(556)
- /// 标题字体
- public var titleFont = UIFont.boldSystemFont(ofSize: 18)
- /// 正文字体
- public var bodyFont = UIFont.systemFont(ofSize: 16)
- /// 标题最多行数
- public var titleMaxLines = Int(1)
- /// 正文最多行数
- public var bodyMaxLines = Int(10)
/// 圆角半径
public var cornerRadius = CGFloat(12)
-
+ /// 余量:元素与元素之间的距离
public var margin = CGFloat(8)
-
+ /// 填充:元素内部控件距离元素边界的距离
public var padding = CGFloat(16)
+ // MARK: 图标样式
+ /// 图标、default按钮的颜色
+ public var tintColor: UIColor?
+ /// 图标尺寸
public var iconSize = CGSize(width: 48, height: 48)
- public var tintColor: UIColor?
- /// 加载视图
- lazy var loadSubviews: (ProHUD.Toast) -> Void = {
- return { (vc) in
- debugPrint(vc, "loadSubviews")
- vc.view.tintColor = toastConfig.tintColor
- vc.view.addSubview(vc.titleLabel)
- vc.view.addSubview(vc.bodyLabel)
- vc.view.addSubview(vc.imageView)
-
- }
- }()
+ // MARK: 文本样式
+ /// 标题字体
+ public var titleFont = UIFont.boldSystemFont(ofSize: 18)
+ /// 标题最多行数
+ public var titleMaxLines = Int(1)
- /// 更新视图
- lazy var reloadData: (ProHUD.Toast) -> Void = {
- return { (vc) in
- debugPrint(vc, "reloadData")
- // 设置数据
- let imgStr: String
- switch vc.vm.scene {
- case .success:
- imgStr = "ProHUDSuccess"
- case .warning:
- imgStr = "ProHUDWarning"
- case .error:
- imgStr = "ProHUDError"
- case .loading:
- imgStr = "ProHUDLoading"
- case .confirm:
- imgStr = "ProHUDMessage"
- case .delete:
- imgStr = "ProHUDTrash"
- default:
- imgStr = "ProHUDMessage"
- }
- let img = vc.vm.icon ?? ProHUD.image(named: imgStr)
- vc.imageView.image = img
- vc.titleLabel.textColor = UIColorForPrimaryLabel
- vc.titleLabel.text = vc.vm.title
- vc.bodyLabel.textColor = UIColorForSecondaryLabel
- vc.bodyLabel.text = vc.vm.message
- }
- }()
+ /// 正文字体
+ public var bodyFont = UIFont.systemFont(ofSize: 16)
+ /// 正文最多行数
+ public var bodyMaxLines = Int(10)
- /// 更新视图
- lazy var layoutSubviews: (ProHUD.Toast) -> Void = {
- return { (vc) in
- debugPrint(vc, "layoutSubviews")
- let config = toastConfig
- let scene = vc.vm.scene
-
- vc.imageView.snp.makeConstraints { (mk) in
- mk.top.equalToSuperview().offset(config.padding)
- mk.leading.equalToSuperview().offset(config.padding)
- mk.bottom.lessThanOrEqualToSuperview().offset(-config.padding)
- mk.width.height.equalTo(config.iconSize)
- }
- vc.titleLabel.snp.makeConstraints { (mk) in
- mk.top.equalToSuperview().offset(config.padding)
- mk.leading.equalTo(vc.imageView.snp.trailing).offset(config.margin)
- mk.leading.greaterThanOrEqualToSuperview().offset(config.padding)
- mk.trailing.equalToSuperview().offset(-config.padding)
- }
- vc.bodyLabel.snp.makeConstraints { (mk) in
- mk.top.equalTo(vc.titleLabel.snp.bottom).offset(config.margin)
- mk.leading.trailing.equalTo(vc.titleLabel)
- mk.bottom.lessThanOrEqualToSuperview().offset(-config.padding)
- }
-
- vc.view.layoutIfNeeded()
- }
- }()
- /// 加载视图
+ /// 加载视图(如果需要完全自定义整个View,可以重写这个)
/// - Parameter callback: 回调代码
public mutating func loadSubviews(_ callback: @escaping (ProHUD.Toast) -> Void) {
- loadSubviews = callback
+ privLoadSubviews = callback
}
/// 更新视图
/// - Parameter callback: 回调代码
public mutating func reloadData(_ callback: @escaping (ProHUD.Toast) -> Void) {
- reloadData = callback
+ privReloadData = callback
}
}
}
-internal var toastConfig = ProHUD.Configuration.Toast()
+// MARK: - 默认实现
-public extension ProHUD {
- static func configToast(_ config: (inout Configuration.Toast) -> Void) {
- config(&toastConfig)
+internal extension ProHUD.Configuration.Toast {
+ var loadSubviews: (ProHUD.Toast) -> Void {
+ return privLoadSubviews
+ }
+ var reloadData: (ProHUD.Toast) -> Void {
+ return privReloadData
}
}
+
+fileprivate var privLoadSubviews: (ProHUD.Toast) -> Void = {
+ return { (vc) in
+ debug(vc, "loadSubviews")
+ vc.view.tintColor = cfg.toast.tintColor
+ vc.view.addSubview(vc.titleLabel)
+ vc.view.addSubview(vc.bodyLabel)
+ vc.view.addSubview(vc.imageView)
+ }
+}()
+
+fileprivate var privReloadData: (ProHUD.Toast) -> Void = {
+ return { (vc) in
+ debug(vc, "reloadData")
+ let config = cfg.toast
+ let scene = vc.vm.scene
+ // 设置数据
+ let imgStr: String
+ switch vc.vm.scene {
+ case .success:
+ imgStr = "ProHUDSuccess"
+ case .warning:
+ imgStr = "ProHUDWarning"
+ case .error:
+ imgStr = "ProHUDError"
+ case .loading:
+ imgStr = "ProHUDLoading"
+ case .confirm:
+ imgStr = "ProHUDMessage"
+ case .delete:
+ imgStr = "ProHUDTrash"
+ default:
+ imgStr = "ProHUDMessage"
+ }
+ let img = vc.vm.icon ?? ProHUD.image(named: imgStr)
+ vc.imageView.image = img
+ vc.titleLabel.textColor = cfg.primaryLabelColor
+ vc.titleLabel.text = vc.vm.title
+ vc.bodyLabel.textColor = cfg.secondaryLabelColor
+ vc.bodyLabel.text = vc.vm.message
+
+ // 更新布局
+ vc.imageView.snp.makeConstraints { (mk) in
+ mk.top.equalToSuperview().offset(config.padding)
+ mk.leading.equalToSuperview().offset(config.padding)
+ mk.bottom.lessThanOrEqualToSuperview().offset(-config.padding)
+ mk.width.height.equalTo(config.iconSize)
+ }
+ vc.titleLabel.snp.makeConstraints { (mk) in
+ mk.top.equalToSuperview().offset(config.padding)
+ mk.leading.equalTo(vc.imageView.snp.trailing).offset(config.margin)
+ mk.leading.greaterThanOrEqualToSuperview().offset(config.padding)
+ mk.trailing.equalToSuperview().offset(-config.padding)
+ }
+ vc.bodyLabel.snp.makeConstraints { (mk) in
+ mk.top.equalTo(vc.titleLabel.snp.bottom).offset(config.margin)
+ mk.leading.trailing.equalTo(vc.titleLabel)
+ mk.bottom.lessThanOrEqualToSuperview().offset(-config.padding)
+ }
+
+ vc.view.layoutIfNeeded()
+ }
+}()
diff --git a/ProHUD/Toast/ToastController.swift b/ProHUD/Toast/ToastController.swift
index 966f2cd..5228e5c 100644
--- a/ProHUD/Toast/ToastController.swift
+++ b/ProHUD/Toast/ToastController.swift
@@ -24,20 +24,20 @@ public extension ProHUD {
/// 标题
internal lazy var titleLabel: UILabel = {
let lb = UILabel()
- lb.textColor = UIColorForPrimaryLabel
- lb.font = toastConfig.titleFont
+ lb.textColor = cfg.primaryLabelColor
+ lb.font = cfg.toast.titleFont
lb.textAlignment = .justified
- lb.numberOfLines = toastConfig.titleMaxLines
+ lb.numberOfLines = cfg.toast.titleMaxLines
return lb
}()
/// 正文
internal lazy var bodyLabel: UILabel = {
let lb = UILabel()
- lb.textColor = UIColorForSecondaryLabel
- lb.font = toastConfig.bodyFont
+ lb.textColor = cfg.secondaryLabelColor
+ lb.font = cfg.toast.bodyFont
lb.textAlignment = .justified
- lb.numberOfLines = toastConfig.bodyMaxLines
+ lb.numberOfLines = cfg.toast.bodyMaxLines
return lb
}()
@@ -50,7 +50,7 @@ public extension ProHUD {
vev.effect = UIBlurEffect.init(style: .extraLight)
}
vev.layer.masksToBounds = true
- vev.layer.cornerRadius = toastConfig.cornerRadius
+ vev.layer.cornerRadius = cfg.toast.cornerRadius
return vev
}()
@@ -84,9 +84,8 @@ public extension ProHUD {
}
// 布局
- toastConfig.loadSubviews(self)
- toastConfig.reloadData(self)
- toastConfig.layoutSubviews(self)
+ cfg.toast.loadSubviews(self)
+ cfg.toast.reloadData(self)
// 点击
let tap = UITapGestureRecognizer(target: self, action: #selector(privDidTapped(_:)))
@@ -137,28 +136,6 @@ public extension ProHUD {
return self
}
-// internal func updateFrame() {
-// let config = toastConfig
-// var f = UIScreen.main.bounds
-// contentStack.frame.size.width = CGFloat.minimum(f.width - 4 * config.margin, config.maxWidth)
-// titleLabel?.sizeToFit()
-// messageLabel?.sizeToFit()
-// contentStack.layoutIfNeeded()
-// f.size.width = contentStack.frame.size.width
-// f.size.height = (textStack.arrangedSubviews.last?.frame.maxY ?? 0) + config.margin
-// debugPrint(f)
-// func updateFrame(_ frame: CGRect) -> CGRect {
-// return CGRect(origin: CGPoint(x: config.margin, y: config.margin), size: frame.size)
-// }
-// func superBounds(_ frame: CGRect) -> CGRect {
-// return CGRect(x: 0, y: 0, width: frame.width + 2 * config.margin, height: frame.height + 2 * config.margin)
-// }
-// contentStack.frame = updateFrame(f)
-// contentView.frame = superBounds(f)
-// view.frame = superBounds(f)
-// window?.frame = superBounds(f)
-// hud.updateToastsLayout()
-// }
// MARK: 设置函数
@@ -200,8 +177,7 @@ public extension ProHUD {
vm.title = title
vm.message = message
vm.icon = icon
- toastConfig.reloadData(self)
- toastConfig.layoutSubviews(self)
+ cfg.toast.reloadData(self)
return self
}
@@ -248,7 +224,7 @@ public extension ProHUD {
@discardableResult
func show(_ toast: Toast) -> Toast {
- let config = toastConfig
+ let config = cfg.toast
let isNew: Bool
if toast.window == nil {
let w = ToastWindow(frame: .zero)
@@ -369,7 +345,7 @@ internal extension ProHUD {
func f() {
let top = Inspire.shared.screen.updatedSafeAreaInsets.top
for (i, e) in toasts.enumerated() {
- let config = toastConfig
+ let config = cfg.toast
if let window = e.window {
var y = window.frame.origin.y
if i == 0 {
@@ -411,7 +387,7 @@ internal extension ProHUD {
} else if toasts.count == 1 {
toasts.removeAll()
} else {
- debugPrint("漏洞:已经没有toast了")
+ debug("漏洞:已经没有toast了")
}
}