This commit is contained in:
xaoxuu 2019-08-03 17:48:37 +08:00
parent 3639558a9c
commit ba1e0ecec0
17 changed files with 548 additions and 723 deletions

View File

@ -33,7 +33,7 @@
<key>UIRequiresFullScreen</key> <key>UIRequiresFullScreen</key>
<false/> <false/>
<key>UIStatusBarHidden</key> <key>UIStatusBarHidden</key>
<false/> <true/>
<key>UIStatusBarStyle</key> <key>UIStatusBarStyle</key>
<string>UIStatusBarStyleDefault</string> <string>UIStatusBarStyleDefault</string>
<key>UISupportedInterfaceOrientations</key> <key>UISupportedInterfaceOrientations</key>

View File

@ -16,17 +16,12 @@ class ViewController: UIViewController {
// Do any additional setup after loading the view. // Do any additional setup after loading the view.
ProHUD.configAlert { (alert) in ProHUD.config { (cfg) in
alert.minimizeTimeout = 3 // cfg.enableDebugPrint = false
cfg.alert { (a) in
} a.forceQuitTimer = 2
ProHUD.configGuard { (g) in }
g.tintColor = .success // cfg.primaryLabelColor = .purple
}
ProHUD.configToast { (toast) in
// toast.backgroundColorForScene { (scene) -> UIColor? in
// return UIColor.yellow
// }
} }
} }
@ -71,7 +66,8 @@ class ViewController: UIViewController {
let g = ProHUD.Guard(title: "请求权限", message: "请打开相机权限开关,否则无法进行测量。") let g = ProHUD.Guard(title: "请求权限", message: "请打开相机权限开关,否则无法进行测量。")
// g.view.tintColor = .warning // g.view.tintColor = .warning
// g.loadBody(g.description) // g.loadBody(g.description)
g.loadTitle("呵呵")
g.loadBody("请打开相机权限开关,否则无法进行测量。请打开相机权限开关,否则无法进行测量。")
g.loadButton(style: .default, title: "测试弹窗", action: { [weak self] in g.loadButton(style: .default, title: "测试弹窗", action: { [weak self] in
self?.testToast() self?.testToast()
}) })

View File

@ -12,8 +12,6 @@
CD16490F22EF09D50077988C /* AlertView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD16490E22EF09D50077988C /* AlertView.swift */; }; CD16490F22EF09D50077988C /* AlertView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD16490E22EF09D50077988C /* AlertView.swift */; };
CD16491222EF0D900077988C /* HUDView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD16491122EF0D900077988C /* HUDView.swift */; }; CD16491222EF0D900077988C /* HUDView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD16491122EF0D900077988C /* HUDView.swift */; };
CD16491422EF12220077988C /* ProHUD.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = CD16491322EF12220077988C /* ProHUD.xcassets */; }; 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 */; }; CD6CD86C22F1858F00F4FD4A /* ToastModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD6CD86B22F1858F00F4FD4A /* ToastModel.swift */; };
CD6CD86E22F185A000F4FD4A /* ToastView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD6CD86D22F185A000F4FD4A /* ToastView.swift */; }; CD6CD86E22F185A000F4FD4A /* ToastView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD6CD86D22F185A000F4FD4A /* ToastView.swift */; };
CD6CD87022F185A700F4FD4A /* ToastController.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD6CD86F22F185A700F4FD4A /* ToastController.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 = "<group>"; }; CD16490E22EF09D50077988C /* AlertView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AlertView.swift; sourceTree = "<group>"; };
CD16491122EF0D900077988C /* HUDView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HUDView.swift; sourceTree = "<group>"; }; CD16491122EF0D900077988C /* HUDView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HUDView.swift; sourceTree = "<group>"; };
CD16491322EF12220077988C /* ProHUD.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = ProHUD.xcassets; sourceTree = "<group>"; }; CD16491322EF12220077988C /* ProHUD.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = ProHUD.xcassets; sourceTree = "<group>"; };
CD67038F22E7F7B60072C96A /* HUDForToast.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HUDForToast.swift; sourceTree = "<group>"; };
CD67039122E7F7BC0072C96A /* HUDForGuard.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HUDForGuard.swift; sourceTree = "<group>"; };
CD6CD86B22F1858F00F4FD4A /* ToastModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ToastModel.swift; sourceTree = "<group>"; }; CD6CD86B22F1858F00F4FD4A /* ToastModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ToastModel.swift; sourceTree = "<group>"; };
CD6CD86D22F185A000F4FD4A /* ToastView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ToastView.swift; sourceTree = "<group>"; }; CD6CD86D22F185A000F4FD4A /* ToastView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ToastView.swift; sourceTree = "<group>"; };
CD6CD86F22F185A700F4FD4A /* ToastController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ToastController.swift; sourceTree = "<group>"; }; CD6CD86F22F185A700F4FD4A /* ToastController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ToastController.swift; sourceTree = "<group>"; };
@ -122,8 +118,6 @@
CD95D21F22E72C4C007559A3 /* ProHUD.h */, CD95D21F22E72C4C007559A3 /* ProHUD.h */,
CD16491322EF12220077988C /* ProHUD.xcassets */, CD16491322EF12220077988C /* ProHUD.xcassets */,
CD95D26A22E72DB3007559A3 /* ProHUD.swift */, CD95D26A22E72DB3007559A3 /* ProHUD.swift */,
CD67038F22E7F7B60072C96A /* HUDForToast.swift */,
CD67039122E7F7BC0072C96A /* HUDForGuard.swift */,
CDB6A07C22EEF19D00AF6CF0 /* HUDConfig.swift */, CDB6A07C22EEF19D00AF6CF0 /* HUDConfig.swift */,
CDB6A07A22EEF06500AF6CF0 /* HUDController.swift */, CDB6A07A22EEF06500AF6CF0 /* HUDController.swift */,
CD16491122EF0D900077988C /* HUDView.swift */, CD16491122EF0D900077988C /* HUDView.swift */,
@ -219,12 +213,10 @@
CD6CD87B22F185D600F4FD4A /* GuardView.swift in Sources */, CD6CD87B22F185D600F4FD4A /* GuardView.swift in Sources */,
CD95D26922E72DA1007559A3 /* AlertController.swift in Sources */, CD95D26922E72DA1007559A3 /* AlertController.swift in Sources */,
CD6CD87922F185D000F4FD4A /* GuardConfig.swift in Sources */, CD6CD87922F185D000F4FD4A /* GuardConfig.swift in Sources */,
CD67039222E7F7BC0072C96A /* HUDForGuard.swift in Sources */,
CDB6A07D22EEF19D00AF6CF0 /* HUDConfig.swift in Sources */, CDB6A07D22EEF19D00AF6CF0 /* HUDConfig.swift in Sources */,
CD16490F22EF09D50077988C /* AlertView.swift in Sources */, CD16490F22EF09D50077988C /* AlertView.swift in Sources */,
CD6CD86E22F185A000F4FD4A /* ToastView.swift in Sources */, CD6CD86E22F185A000F4FD4A /* ToastView.swift in Sources */,
CD6CD87222F185AF00F4FD4A /* ToastConfig.swift in Sources */, CD6CD87222F185AF00F4FD4A /* ToastConfig.swift in Sources */,
CD67039022E7F7B60072C96A /* HUDForToast.swift in Sources */,
CD6CD87522F185C200F4FD4A /* GuardController.swift in Sources */, CD6CD87522F185C200F4FD4A /* GuardController.swift in Sources */,
CD6CD87022F185A700F4FD4A /* ToastController.swift in Sources */, CD6CD87022F185A700F4FD4A /* ToastController.swift in Sources */,
CD95D26B22E72DB3007559A3 /* ProHUD.swift in Sources */, CD95D26B22E72DB3007559A3 /* ProHUD.swift in Sources */,

View File

@ -1,5 +1,5 @@
// //
// AlertConfig.swift // cfg.alert.swift
// ProHUD // ProHUD
// //
// Created by xaoxuu on 2019/7/29. // Created by xaoxuu on 2019/7/29.
@ -30,8 +30,6 @@ public extension ProHUD.Configuration {
// MARK: // MARK:
/// ///
public var titleFont = UIFont.boldSystemFont(ofSize: 22) public var titleFont = UIFont.boldSystemFont(ofSize: 22)
///
public var titleColor = UIColorForPrimaryLabel
/// ///
public var titleMaxLines = Int(1) public var titleMaxLines = Int(1)
@ -40,8 +38,6 @@ public extension ProHUD.Configuration {
/// ///
public var bodyFont = UIFont.systemFont(ofSize: 17) public var bodyFont = UIFont.systemFont(ofSize: 17)
///
public var bodyColor = UIColorForSecondaryLabel
/// ///
public var bodyMaxLines = Int(5) public var bodyMaxLines = Int(5)
@ -49,240 +45,257 @@ public extension ProHUD.Configuration {
/// ///
public var buttonFont = UIFont.boldSystemFont(ofSize: 18) public var buttonFont = UIFont.boldSystemFont(ofSize: 18)
// MARK:
/// 退
public var minimizeTimeout = TimeInterval(10)
///
public var minimizeTitle = String("隐藏窗口")
// MARK: // MARK:
/// ///
lazy var loadSubviews: (ProHUD.Alert, Alert) -> Void = { /// - Parameter callback:
return { (vc, config) in public mutating func loadSubviews(_ callback: @escaping (ProHUD.Alert) -> Void) {
debugPrint(vc, "loadSubviews") privLoadSubviews = callback
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)
}
}
}
}()
/// ///
lazy var updateFrame: (ProHUD.Alert, Alert) -> Void = { /// - Parameter callback:
return { (vc, config) in public mutating func reloadData(_ callback: @escaping (ProHUD.Alert) -> Void) {
debugPrint(vc, "updateFrame") privReloadData = callback
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()
}
}
}
}()
/// /// 退
lazy var showNavButtons: (ProHUD.Alert, Alert) -> Void = { public var forceQuitTimer = TimeInterval(10)
return { (vc, config) in
debugPrint(vc, "showNavButtons") /// 退
let btn = ProHUD.Alert.Button.minimizeButton() public var forceQuitTitle = "隐藏窗口"
let bg = ProHUD.BlurView()
bg.layer.masksToBounds = true /// 退
bg.layer.cornerRadius = config.cornerRadius /// - Parameter callback:
if let last = vc.view.subviews.last { public mutating func loadForceQuitButton(_ callback: @escaping (ProHUD.Alert) -> Void) {
vc.view.insertSubview(bg, belowSubview: last) 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 { } 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 if vc.vm.message?.count ?? 0 > 0 {
mk.leading.trailing.equalTo(vc.contentView) // message
mk.top.equalTo(vc.contentView.snp.bottom).offset(config.margin) vc.titleLabel?.font = config.titleFont
} else {
// message
vc.titleLabel?.font = config.boldTextFont
} }
bg.contentView.addSubview(btn) } else {
btn.snp.makeConstraints { (mk) in vc.titleLabel?.removeFromSuperview()
mk.edges.equalToSuperview() }
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 if vc.vm.title?.count ?? 0 > 0 {
bg.layoutIfNeeded() // title
bg.transform = .init(translationX: 0, y: -2*(config.margin+bg.frame.size.height)) 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 { UIView.animateForAlert {
bg.alpha = 1 vc.contentStack.addArrangedSubview(vc.actionStack)
bg.transform = .identity vc.view.layoutIfNeeded()
}
vc.addTouchUpAction(for: btn) { [weak vc] in
debugPrint("点击了隐藏")
vc?.minimizeCallback?()
vc?.remove()
} }
} }
}() // iPad
if isPortrait == false {
/// vc.actionStack.axis = .horizontal
/// - Parameter callback: vc.actionStack.alignment = .fill
public mutating func loadSubviews(_ callback: @escaping (ProHUD.Alert, Alert) -> Void) { vc.actionStack.distribution = .fillEqually
loadSubviews = callback }
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 {
/// - Parameter callback: vc.view.layoutIfNeeded()
public mutating func updateFrame(_ callback: @escaping (ProHUD.Alert, Alert) -> Void) { vc.imageView?.transform = .init(scaleX: 0.75, y: 0.75)
updateFrame = callback UIView.animateForAlert {
vc.imageView?.transform = .identity
vc.view.layoutIfNeeded()
}
} else {
UIView.animateForAlert {
vc.view.layoutIfNeeded()
}
} }
} }
} }()
internal var alertConfig = ProHUD.Configuration.Alert() fileprivate var privLoadForceQuitButton: (ProHUD.Alert) -> Void = {
return { (vc) in
public extension ProHUD { debug(vc, "showNavButtons")
static func configAlert(_ config: (inout Configuration.Alert) -> Void) { let config = cfg.alert
config(&alertConfig) 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()
}
} }
} }()

View File

@ -18,14 +18,14 @@ public extension ProHUD {
/// icontextStackactionStack) /// icontextStackactionStack)
internal var contentStack: StackContainer = { internal var contentStack: StackContainer = {
let stack = StackContainer() let stack = StackContainer()
stack.spacing = alertConfig.margin stack.spacing = cfg.alert.margin
return stack return stack
}() }()
/// ///
internal var textStack: StackContainer = { internal var textStack: StackContainer = {
let stack = StackContainer() let stack = StackContainer()
stack.spacing = alertConfig.margin stack.spacing = cfg.alert.margin
return stack return stack
}() }()
internal var imageView: UIImageView? internal var imageView: UIImageView?
@ -35,7 +35,7 @@ public extension ProHUD {
internal var actionStack: StackContainer = { internal var actionStack: StackContainer = {
let stack = StackContainer() let stack = StackContainer()
stack.alignment = .fill stack.alignment = .fill
stack.spacing = alertConfig.margin stack.spacing = cfg.alert.margin
return stack return stack
}() }()
@ -56,7 +56,7 @@ public extension ProHUD {
/// - Parameter icon: /// - Parameter icon:
public convenience init(scene: Scene = .default, title: String? = nil, message: String? = nil, icon: UIImage? = nil) { public convenience init(scene: Scene = .default, title: String? = nil, message: String? = nil, icon: UIImage? = nil) {
self.init() self.init()
view.tintColor = alertConfig.tintColor view.tintColor = cfg.alert.tintColor
vm.scene = scene vm.scene = scene
vm.title = title vm.title = title
vm.message = message vm.message = message
@ -151,7 +151,7 @@ public extension ProHUD {
vm.message = message vm.message = message
vm.scene = scene vm.scene = scene
vm.icon = icon vm.icon = icon
alertConfig.updateFrame(self, alertConfig) cfg.alert.reloadData(self)
return self return self
} }
@ -217,8 +217,8 @@ fileprivate extension ProHUD.Alert {
willLayout = DispatchWorkItem(block: { [weak self] in willLayout = DispatchWorkItem(block: { [weak self] in
if let a = self { if let a = self {
// //
alertConfig.loadSubviews(a, alertConfig) cfg.alert.loadSubviews(a)
alertConfig.updateFrame(a, alertConfig) cfg.alert.reloadData(a)
// //
if let t = a.timeout, t > 0 { if let t = a.timeout, t > 0 {
a.timeoutBlock = DispatchWorkItem(block: { [weak self] in a.timeoutBlock = DispatchWorkItem(block: { [weak self] in
@ -229,13 +229,13 @@ fileprivate extension ProHUD.Alert {
a.timeoutBlock = nil 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 a.showNavButtonsBlock = DispatchWorkItem(block: { [weak self] in
if let s = self { 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 { } else if alerts.count == 1 {
alerts.removeAll() alerts.removeAll()
} else { } else {
debugPrint("漏洞已经没有alert了") debug("漏洞已经没有alert了")
} }
} }

View File

@ -13,15 +13,15 @@ internal extension ProHUD.Alert {
class func actionButton(title: String?) -> UIButton { class func actionButton(title: String?) -> UIButton {
let btn = Button(type: .system) let btn = Button(type: .system)
btn.setTitle(title, for: .normal) btn.setTitle(title, for: .normal)
btn.layer.cornerRadius = alertConfig.cornerRadius / 2 btn.layer.cornerRadius = cfg.alert.cornerRadius / 2
btn.titleLabel?.font = alertConfig.buttonFont btn.titleLabel?.font = cfg.alert.buttonFont
return btn return btn
} }
func update(style: UIAlertAction.Style) { func update(style: UIAlertAction.Style) {
let pd = CGFloat(8) let pd = CGFloat(8)
if style != .cancel { 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) contentEdgeInsets = .init(top: pd*1.5, left: pd*1.5, bottom: pd*1.5, right: pd*1.5)
} else { } else {
contentEdgeInsets = .init(top: pd*0.5, left: pd*1.5, bottom: pd*0.5, right: pd*1.5) 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: case .destructive:
setTitleColor(.init(red: 244/255, green: 67/255, blue: 54/255, alpha: 1), for: .normal) setTitleColor(.init(red: 244/255, green: 67/255, blue: 54/255, alpha: 1), for: .normal)
case .cancel: case .cancel:
setTitleColor(UIColorForSecondaryLabel, for: .normal) setTitleColor(cfg.secondaryLabelColor, for: .normal)
@unknown default: @unknown default:
break break
} }
tag = style.rawValue tag = style.rawValue
} }
class func minimizeButton() -> UIButton { class func forceQuitButton() -> UIButton {
let btn = Button(type: .system) 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.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.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.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 return btn
} }

View File

@ -1,5 +1,5 @@
// //
// GuardConfig.swift // cfg.guard.swift
// ProHUD // ProHUD
// //
// Created by xaoxuu on 2019/7/31. // Created by xaoxuu on 2019/7/31.
@ -29,13 +29,9 @@ public extension ProHUD.Configuration {
// MARK: // MARK:
/// ///
public var titleFont = UIFont.boldSystemFont(ofSize: 22) public var titleFont = UIFont.boldSystemFont(ofSize: 22)
///
public var titleColor = UIColorForPrimaryLabel
/// ///
public var bodyFont = UIFont.systemFont(ofSize: 18) public var bodyFont = UIFont.systemFont(ofSize: 18)
///
public var bodyColor = UIColorForSecondaryLabel
// MARK: // MARK:
/// ///
@ -45,111 +41,89 @@ public extension ProHUD.Configuration {
/// ///
public var buttonCornerRadius = CGFloat(12) 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 = { /// - Parameter callback:
return { (vc, config) in public mutating func loadSubviews(_ callback: @escaping (ProHUD.Guard) -> Void) {
debugPrint(vc, "loadSubviews") privLoadSubviews = callback
// background }
vc.view.tintColor = config.tintColor
vc.view.backgroundColor = UIColor(white: 0, alpha: 0) ///
vc.view.addSubview(vc.contentView) /// - Parameter callback:
var width = UIScreen.main.bounds.width public mutating func reloadData(_ callback: @escaping (ProHUD.Guard) -> Void) {
if width > config.cardMaxWidth { privReloadData = callback
// iPad }
width = config.cardMaxWidth
vc.contentView.layer.masksToBounds = true }
vc.contentView.layer.cornerRadius = config.cardCornerRadius }
// 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 { } else {
vc.contentView.layer.shadowRadius = 4 mk.bottom.equalToSuperview()
vc.contentView.layer.shadowOffset = .init(width: 0, height: 2)
vc.contentView.layer.shadowOpacity = 0.12
} }
vc.contentView.snp.makeConstraints { (mk) in } else if UIDevice.current.userInterfaceIdiom == .pad {
mk.centerX.equalToSuperview() mk.centerY.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)
} }
}() mk.width.equalTo(width)
}
/// // stack
lazy var updateFrame: (ProHUD.Guard, Guard) -> Void = { vc.contentStack.snp.makeConstraints { (mk) in
return { (vc, config) in mk.top.equalToSuperview().offset(config.padding + config.margin)
debugPrint(vc, "updateFrame") 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)
}
}

View File

@ -17,7 +17,7 @@ public extension ProHUD {
/// textStackactionStack) /// textStackactionStack)
public var contentStack: StackContainer = { public var contentStack: StackContainer = {
let stack = StackContainer() let stack = StackContainer()
stack.spacing = guardConfig.padding + guardConfig.margin stack.spacing = cfg.guard.padding + cfg.guard.margin
stack.alignment = .fill stack.alignment = .fill
return stack return stack
}() }()
@ -25,19 +25,19 @@ public extension ProHUD {
/// ///
public var textStack: StackContainer = { public var textStack: StackContainer = {
let stack = StackContainer() let stack = StackContainer()
stack.spacing = guardConfig.margin stack.spacing = cfg.guard.margin
stack.alignment = .fill stack.alignment = .fill
return stack return stack
}() }()
public var titleLabel: UILabel? // public var titleLabel: UILabel?
public var bodyLabel: UILabel? // public var bodyLabel: UILabel?
/// ///
public var actionStack: StackContainer = { public var actionStack: StackContainer = {
let stack = StackContainer() let stack = StackContainer()
stack.alignment = .fill stack.alignment = .fill
stack.spacing = guardConfig.margin stack.spacing = cfg.guard.margin
return stack return stack
}() }()
@ -57,15 +57,15 @@ public extension ProHUD {
public convenience init(title: String? = nil, message: String? = nil) { public convenience init(title: String? = nil, message: String? = nil) {
self.init() self.init()
view = View() view = View()
view.tintColor = guardConfig.tintColor view.tintColor = cfg.guard.tintColor
if let _ = title { if let _ = title {
loadTitle(title) loadTitle(title)
} }
if let _ = message { if let _ = message {
loadBody(message) loadBody(message)
} }
guardConfig.loadSubviews(self, guardConfig) cfg.guard.loadSubviews(self)
// willLayoutSubviews() cfg.guard.reloadData(self)
// //
let tap = UITapGestureRecognizer(target: self, action: #selector(privDidTapped(_:))) let tap = UITapGestureRecognizer(target: self, action: #selector(privDidTapped(_:)))
@ -81,7 +81,7 @@ public extension ProHUD {
} }
deinit { deinit {
debugPrint(self, "deinit") debug(self, "deinit")
} }
public func push(to viewController: UIViewController? = nil) { public func push(to viewController: UIViewController? = nil) {
@ -106,7 +106,7 @@ public extension ProHUD {
public func pop() { public func pop() {
if displaying { if displaying {
debugPrint("pop") debug("pop")
displaying = false displaying = false
view.isUserInteractionEnabled = false view.isUserInteractionEnabled = false
self.removeFromParent() self.removeFromParent()
@ -126,21 +126,31 @@ public extension ProHUD.Guard {
@discardableResult @discardableResult
func loadTitle(_ text: String?) -> UILabel { func loadTitle(_ text: String?) -> UILabel {
guardConfig.loadTitleLabel(self, guardConfig) let lb = UILabel()
let lb = titleLabel! lb.font = cfg.guard.titleFont
lb.textColor = cfg.primaryLabelColor
lb.numberOfLines = 0
lb.textAlignment = .justified
lb.text = text lb.text = text
if textStack.arrangedSubviews.count > 0 { textStack.addArrangedSubview(lb)
textStack.insertArrangedSubview(lb, at: 0) 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 { } else {
textStack.addArrangedSubview(lb) // Fallback on earlier versions
} }
return lb return lb
} }
@discardableResult @discardableResult
func loadBody(_ text: String?) -> UILabel { func loadBody(_ text: String?) -> UILabel {
guardConfig.loadBodyLabel(self, guardConfig) let lb = UILabel()
let lb = bodyLabel! lb.font = cfg.guard.bodyFont
lb.textColor = cfg.secondaryLabelColor
lb.numberOfLines = 0
lb.textAlignment = .justified
lb.text = text lb.text = text
textStack.addArrangedSubview(lb) textStack.addArrangedSubview(lb)
return lb return lb
@ -149,7 +159,7 @@ public extension ProHUD.Guard {
@discardableResult @discardableResult
func loadButton(style: UIAlertAction.Style, title: String?, action: (() -> Void)? = nil) -> UIButton { func loadButton(style: UIAlertAction.Style, title: String?, action: (() -> Void)? = nil) -> UIButton {
let btn = Button.actionButton(title: title) let btn = Button.actionButton(title: title)
btn.titleLabel?.font = guardConfig.buttonFont btn.titleLabel?.font = cfg.guard.buttonFont
if actionStack.superview == nil { if actionStack.superview == nil {
contentStack.addArrangedSubview(actionStack) contentStack.addArrangedSubview(actionStack)
} }
@ -189,7 +199,7 @@ fileprivate extension ProHUD.Guard {
func translateOut() { func translateOut() {
view.backgroundColor = UIColor(white: 0, alpha: 0) 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)
} }

View File

@ -42,8 +42,8 @@ internal extension ProHUD.Guard {
class func actionButton(title: String?) -> Button { class func actionButton(title: String?) -> Button {
let btn = Button(type: .system) let btn = Button(type: .system)
btn.setTitle(title, for: .normal) btn.setTitle(title, for: .normal)
btn.layer.cornerRadius = guardConfig.buttonCornerRadius btn.layer.cornerRadius = cfg.guard.buttonCornerRadius
btn.titleLabel?.font = guardConfig.buttonFont btn.titleLabel?.font = cfg.guard.buttonFont
return btn return btn
} }
@ -62,7 +62,7 @@ internal extension ProHUD.Guard {
backgroundColor = .init(red: 244/255, green: 67/255, blue: 54/255, alpha: 1) backgroundColor = .init(red: 244/255, green: 67/255, blue: 54/255, alpha: 1)
setTitleColor(.white, for: .normal) setTitleColor(.white, for: .normal)
case .cancel: case .cancel:
setTitleColor(UIColorForSecondaryLabel, for: .normal) setTitleColor(cfg.secondaryLabelColor, for: .normal)
@unknown default: @unknown default:
break break
} }

View File

@ -11,9 +11,40 @@ import UIKit
public extension ProHUD { public extension ProHUD {
struct Configuration { struct Configuration {
internal var toast = Toast() /// Debug
internal var alert = Alert() public var enableDebugPrint = true
internal var `guard` = Guard()
/// 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 /// Toast
/// - Parameter callback: /// - 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)
}
}

View File

@ -25,7 +25,7 @@ public class HUDController: UIViewController {
init() { init() {
super.init(nibName: nil, bundle: nil) super.init(nibName: nil, bundle: nil)
print(self, "init") debug(self, "init")
} }
required public init?(coder: NSCoder) { required public init?(coder: NSCoder) {
@ -33,7 +33,7 @@ public class HUDController: UIViewController {
} }
deinit { deinit {
debugPrint(self, "deinit") debug(self, "deinit")
} }
@ -48,14 +48,6 @@ public class HUDController: UIViewController {
internal extension HUDController { 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) { func addTouchUpAction(for button: UIButton, action: @escaping () -> Void) {
button.addTarget(self, action: #selector(didTappedButton(_:)), for: .touchUpInside) button.addTarget(self, action: #selector(didTappedButton(_:)), for: .touchUpInside)
buttonEvents[button] = action buttonEvents[button] = action

View File

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

View File

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

View File

@ -38,7 +38,7 @@ public extension ProHUD {
public override init(frame: CGRect) { public override init(frame: CGRect) {
super.init(frame: frame) super.init(frame: frame)
spacing = alertConfig.margin spacing = cfg.alert.margin
distribution = .fill distribution = .fill
alignment = .center alignment = .center
axis = .vertical axis = .vertical
@ -58,10 +58,8 @@ public extension ProHUD {
if #available(iOS 13.0, *) { if #available(iOS 13.0, *) {
super.init(effect: UIBlurEffect(style: .systemMaterial)) super.init(effect: UIBlurEffect(style: .systemMaterial))
// backgroundColor = UIColor.init(white: 1, alpha: 0.3)
} else { } else {
super.init(effect: UIBlurEffect(style: .extraLight)) super.init(effect: UIBlurEffect(style: .extraLight))
backgroundColor = UIColor.init(white: 1, alpha: 0.66)
} }
} }

View File

@ -14,6 +14,10 @@ public class ProHUD {
public static let shared = ProHUD() public static let shared = ProHUD()
public var config: Configuration {
return cfg
}
internal var toasts = [Toast]() internal var toasts = [Toast]()
internal var alerts = [Alert]() internal var alerts = [Alert]()
@ -22,9 +26,11 @@ public class ProHUD {
} }
// MARK: - Utilities
internal extension ProHUD { internal extension ProHUD {
/// Bundle
static var bundle: Bundle { static var bundle: Bundle {
var b = Bundle.init(for: ProHUD.Alert.self) var b = Bundle.init(for: ProHUD.Alert.self)
let p = b.path(forResource: "ProHUD", ofType: "bundle") let p = b.path(forResource: "ProHUD", ofType: "bundle")
@ -33,7 +39,7 @@ internal extension ProHUD {
} }
return b return b
} }
/// Image
static func image(named: String) -> UIImage? { static func image(named: String) -> UIImage? {
return UIImage.init(named: named, in: bundle, compatibleWith: nil) return UIImage.init(named: named, in: bundle, compatibleWith: nil)
} }
@ -41,63 +47,26 @@ internal extension ProHUD {
} }
///
internal var isPortrait: Bool { internal var isPortrait: Bool {
if UIScreen.main.bounds.width < 500 { if UIDevice.current.userInterfaceIdiom == .phone {
return true if UIApplication.shared.statusBarOrientation.isPortrait {
} else { debug("当前是手机竖屏模式")
return false return true
}
}
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
} else { } else {
// Fallback on earlier versions debug("当前是手机横屏模式")
} }
return .init(white: 0.2, alpha: 1) } else {
debug("非手机设备unspecified、iPad、tv、carPlay")
} }
return false
var dynamicPrimaryLabelColor: UIColor {
return dynamicColor.withAlphaComponent(0.75)
}
var dynamicSecondaryLabelColor: UIColor {
return dynamicColor.withAlphaComponent(0.6)
}
} }
/// Debug
internal func debug(_ items: Any..., separator: String = " ", terminator: String = "\n") {
if cfg.enableDebugPrint {
debugPrint(items, separator: separator, terminator: terminator)
}
}

View File

@ -1,5 +1,5 @@
// //
// ToastConfig.swift // cfg.toast.swift
// ProHUD // ProHUD
// //
// Created by xaoxuu on 2019/7/31. // Created by xaoxuu on 2019/7/31.
@ -10,116 +10,118 @@ import SnapKit
public extension ProHUD.Configuration { public extension ProHUD.Configuration {
struct Toast { struct Toast {
// MARK:
/// iPad /// iPad
public var maxWidth = CGFloat(556) 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 cornerRadius = CGFloat(12)
///
public var margin = CGFloat(8) public var margin = CGFloat(8)
///
public var padding = CGFloat(16) public var padding = CGFloat(16)
// MARK:
/// default
public var tintColor: UIColor?
///
public var iconSize = CGSize(width: 48, height: 48) public var iconSize = CGSize(width: 48, height: 48)
public var tintColor: UIColor? // MARK:
/// ///
lazy var loadSubviews: (ProHUD.Toast) -> Void = { public var titleFont = UIFont.boldSystemFont(ofSize: 18)
return { (vc) in ///
debugPrint(vc, "loadSubviews") public var titleMaxLines = Int(1)
vc.view.tintColor = toastConfig.tintColor
vc.view.addSubview(vc.titleLabel)
vc.view.addSubview(vc.bodyLabel)
vc.view.addSubview(vc.imageView)
}
}()
/// ///
lazy var reloadData: (ProHUD.Toast) -> Void = { public var bodyFont = UIFont.systemFont(ofSize: 16)
return { (vc) in ///
debugPrint(vc, "reloadData") public var bodyMaxLines = Int(10)
//
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
}
}()
/// /// View
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()
}
}()
///
/// - Parameter callback: /// - Parameter callback:
public mutating func loadSubviews(_ callback: @escaping (ProHUD.Toast) -> Void) { public mutating func loadSubviews(_ callback: @escaping (ProHUD.Toast) -> Void) {
loadSubviews = callback privLoadSubviews = callback
} }
/// ///
/// - Parameter callback: /// - Parameter callback:
public mutating func reloadData(_ callback: @escaping (ProHUD.Toast) -> Void) { public mutating func reloadData(_ callback: @escaping (ProHUD.Toast) -> Void) {
reloadData = callback privReloadData = callback
} }
} }
} }
internal var toastConfig = ProHUD.Configuration.Toast() // MARK: -
public extension ProHUD { internal extension ProHUD.Configuration.Toast {
static func configToast(_ config: (inout Configuration.Toast) -> Void) { var loadSubviews: (ProHUD.Toast) -> Void {
config(&toastConfig) 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()
}
}()

View File

@ -24,20 +24,20 @@ public extension ProHUD {
/// ///
internal lazy var titleLabel: UILabel = { internal lazy var titleLabel: UILabel = {
let lb = UILabel() let lb = UILabel()
lb.textColor = UIColorForPrimaryLabel lb.textColor = cfg.primaryLabelColor
lb.font = toastConfig.titleFont lb.font = cfg.toast.titleFont
lb.textAlignment = .justified lb.textAlignment = .justified
lb.numberOfLines = toastConfig.titleMaxLines lb.numberOfLines = cfg.toast.titleMaxLines
return lb return lb
}() }()
/// ///
internal lazy var bodyLabel: UILabel = { internal lazy var bodyLabel: UILabel = {
let lb = UILabel() let lb = UILabel()
lb.textColor = UIColorForSecondaryLabel lb.textColor = cfg.secondaryLabelColor
lb.font = toastConfig.bodyFont lb.font = cfg.toast.bodyFont
lb.textAlignment = .justified lb.textAlignment = .justified
lb.numberOfLines = toastConfig.bodyMaxLines lb.numberOfLines = cfg.toast.bodyMaxLines
return lb return lb
}() }()
@ -50,7 +50,7 @@ public extension ProHUD {
vev.effect = UIBlurEffect.init(style: .extraLight) vev.effect = UIBlurEffect.init(style: .extraLight)
} }
vev.layer.masksToBounds = true vev.layer.masksToBounds = true
vev.layer.cornerRadius = toastConfig.cornerRadius vev.layer.cornerRadius = cfg.toast.cornerRadius
return vev return vev
}() }()
@ -84,9 +84,8 @@ public extension ProHUD {
} }
// //
toastConfig.loadSubviews(self) cfg.toast.loadSubviews(self)
toastConfig.reloadData(self) cfg.toast.reloadData(self)
toastConfig.layoutSubviews(self)
// //
let tap = UITapGestureRecognizer(target: self, action: #selector(privDidTapped(_:))) let tap = UITapGestureRecognizer(target: self, action: #selector(privDidTapped(_:)))
@ -137,28 +136,6 @@ public extension ProHUD {
return self 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: // MARK:
@ -200,8 +177,7 @@ public extension ProHUD {
vm.title = title vm.title = title
vm.message = message vm.message = message
vm.icon = icon vm.icon = icon
toastConfig.reloadData(self) cfg.toast.reloadData(self)
toastConfig.layoutSubviews(self)
return self return self
} }
@ -248,7 +224,7 @@ public extension ProHUD {
@discardableResult @discardableResult
func show(_ toast: Toast) -> Toast { func show(_ toast: Toast) -> Toast {
let config = toastConfig let config = cfg.toast
let isNew: Bool let isNew: Bool
if toast.window == nil { if toast.window == nil {
let w = ToastWindow(frame: .zero) let w = ToastWindow(frame: .zero)
@ -369,7 +345,7 @@ internal extension ProHUD {
func f() { func f() {
let top = Inspire.shared.screen.updatedSafeAreaInsets.top let top = Inspire.shared.screen.updatedSafeAreaInsets.top
for (i, e) in toasts.enumerated() { for (i, e) in toasts.enumerated() {
let config = toastConfig let config = cfg.toast
if let window = e.window { if let window = e.window {
var y = window.frame.origin.y var y = window.frame.origin.y
if i == 0 { if i == 0 {
@ -411,7 +387,7 @@ internal extension ProHUD {
} else if toasts.count == 1 { } else if toasts.count == 1 {
toasts.removeAll() toasts.removeAll()
} else { } else {
debugPrint("漏洞已经没有toast了") debug("漏洞已经没有toast了")
} }
} }