This commit is contained in:
xaoxuu 2019-08-02 13:55:23 +08:00
parent b8763cd45f
commit 082e976f5a
10 changed files with 168 additions and 120 deletions

View File

@ -380,7 +380,7 @@
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
DEVELOPMENT_TEAM = 34W5TB5KD2;
DEVELOPMENT_TEAM = WU2WFZ2B66;
INFOPLIST_FILE = Example/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",

View File

@ -18,6 +18,7 @@ class ViewController: UIViewController {
ProHUD.configAlert { (alert) in
alert.minimizeTimeout = 1
}
}
@ -25,7 +26,12 @@ class ViewController: UIViewController {
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
// let a = ProHUD.show(alert: .delete, title: "", message: "")
ProHUD.show(alert: .delete, title: "确认删除", message: "此操作不可撤销").timeout(nil)
ProHUD.show(alert: .loading, title: "确认删除", message: "此操作不可撤销").timeout(nil)
ProHUD.show(alert: .confirm, title: "确认删除", message: "此操作不可撤销").timeout(3)
//
// a.addAction(style: .destructive, title: "") { [weak a] in
// a?.updateContent(scene: .success, title: "", message: "xxx")
@ -45,36 +51,33 @@ class ViewController: UIViewController {
//
// }
let t = ProHUD.Toast(scene: .loading, title: "正在加载", message: "请稍候片刻")
let a = ProHUD.show(alert : .loading, title: "正在加载", message: "请稍候片刻")
a.didMinimize {
hud.show(t)
}
t.didTapped { [weak t] in
t?.remove()
let a2 = ProHUD.show(alert: .loading, title: "正在加载", message: "马上就要成功了")
DispatchQueue.main.asyncAfter(deadline: .now()+1) {
a2.updateContent(scene: .error, title: "加载失败", message: "点击充实")
a2.addAction(style: .default, title: "重新加载") { [weak a2] in
a2?.updateContent(scene: .success, title: "加载成功", message: "马上就要成功了")
a2?.updateAction(index: 0, style: .default, title: "OK", action: { [weak a2] in
a2?.remove()
}).removeAction(index: 1).removeAction(index: 1)
}.addAction(style: .destructive, title: "终止", action: nil).addAction(style: .cancel, title: "取消", action: nil)
}
}
// let t = ProHUD.Toast(scene: .loading, title: "", message: "")
//
// let a = ProHUD.show(alert : .loading, title: "", message: "")
// a.didMinimize {
// hud.show(t)
// }
// t.didTapped { [weak t] in
// t?.remove()
// let a2 = ProHUD.show(alert: .loading, title: "", message: "")
// DispatchQueue.main.asyncAfter(deadline: .now()+1) {
// let a3 = ProHUD.show(alert: .error, title: "", message: "")
// a3.addAction(style: .default, title: "") { [weak a3] in
// a3?.updateContent(scene: .success, title: "", message: "")
// a3?.updateAction(index: 0, style: .default, title: "OK", action: { [weak a2, a3] in
// a2?.remove()
// a3?.remove()
// }).removeAction(index: 1).removeAction(index: 1)
// }.addAction(style: .destructive, title: "", action: nil).addAction(style: .cancel, title: "", action: nil)
//
// }
//
// }
// ProHUD.show(toast: .loading, title: "", message: "")
// ProHUD.show(toast: .loading, title: "", message: "")
DispatchQueue.main.asyncAfter(deadline: .now()+1) {
}
}
}

View File

@ -11,37 +11,54 @@ import SnapKit
public extension ProHUD.Configuration {
struct Alert {
// MARK:
/// iPad
public var maxWidth = CGFloat(400)
///
public var largeTitleFont = UIFont.boldSystemFont(ofSize: 22)
///
public var titleFont = UIFont.boldSystemFont(ofSize: 18)
///
public var bodyFont = UIFont.systemFont(ofSize: 17)
///
public var buttonFont = UIFont.boldSystemFont(ofSize: 18)
/// 0
public var titleMaxLines = Int(0)
/// 0
public var bodyMaxLines = Int(0)
///
public var cornerRadius = CGFloat(16)
///
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.init(red: 3/255, green: 169/255, blue: 244/255, alpha: 1)
// MARK:
///
public var titleFont = UIFont.boldSystemFont(ofSize: 22)
///
public var titleColor = UIColor(white: 0.2, alpha: 1)
///
public var titleMaxLines = Int(1)
///
///
public var boldTextFont = UIFont.boldSystemFont(ofSize: 18)
///
public var bodyFont = UIFont.systemFont(ofSize: 17)
///
public var bodyColor = UIColor.darkGray
///
public var bodyMaxLines = Int(5)
// MARK:
///
public var buttonFont = UIFont.boldSystemFont(ofSize: 18)
// MARK:
/// 退
public var minimizeTimeout = TimeInterval(10)
///
public var minimizeTitle = String("隐藏窗口")
// MARK:
///
lazy var loadSubviews: (ProHUD.Alert) -> Void = {
return { (vc) in
lazy var loadSubviews: (ProHUD.Alert, Alert) -> Void = {
return { (vc, config) in
debugPrint(vc, "loadSubviews")
vc.view.addSubview(vc.contentView)
vc.contentView.contentView.addSubview(vc.contentStack)
@ -67,8 +84,8 @@ public extension ProHUD.Configuration {
}()
///
lazy var updateFrame: (ProHUD.Alert) -> Void = {
return { (vc) in
lazy var updateFrame: (ProHUD.Alert, Alert) -> Void = {
return { (vc, config) in
debugPrint(vc, "updateFrame")
let isFirstLayout: Bool
// layout
@ -101,10 +118,10 @@ public extension ProHUD.Configuration {
let icon = UIImageView(image: img)
vc.contentStack.addArrangedSubview(icon)
icon.snp.makeConstraints { (mk) in
mk.top.greaterThanOrEqualTo(vc.contentView).offset(alertConfig.padding*2.25)
mk.bottom.lessThanOrEqualTo(vc.contentView).offset(-alertConfig.padding*2.25)
mk.leading.greaterThanOrEqualTo(vc.contentView).offset(alertConfig.padding*4)
mk.trailing.lessThanOrEqualTo(vc.contentView).offset(-alertConfig.padding*4)
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
}
@ -113,10 +130,10 @@ public extension ProHUD.Configuration {
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(alertConfig.padding*1.75)
mk.bottom.lessThanOrEqualTo(vc.contentView).offset(-alertConfig.padding*1.75)
mk.leading.greaterThanOrEqualTo(vc.contentView).offset(alertConfig.padding*2)
mk.trailing.lessThanOrEqualTo(vc.contentView).offset(-alertConfig.padding*2)
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 {
@ -124,18 +141,18 @@ public extension ProHUD.Configuration {
} else {
let title = UILabel()
title.textAlignment = .center
title.numberOfLines = alertConfig.titleMaxLines
title.textColor = UIColor.init(white: 0.2, alpha: 1)
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 = alertConfig.largeTitleFont
vc.titleLabel?.font = config.titleFont
} else {
// message
vc.titleLabel?.font = alertConfig.titleFont
vc.titleLabel?.font = config.boldTextFont
}
} else {
vc.titleLabel?.removeFromSuperview()
@ -146,19 +163,19 @@ public extension ProHUD.Configuration {
} else {
let body = UILabel()
body.textAlignment = .center
body.font = alertConfig.bodyFont
body.numberOfLines = alertConfig.bodyMaxLines
body.textColor = UIColor.darkGray
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 = alertConfig.bodyFont
vc.messageLabel?.font = config.bodyFont
} else {
// title
vc.messageLabel?.font = alertConfig.titleFont
vc.messageLabel?.font = config.boldTextFont
}
} else {
vc.messageLabel?.removeFromSuperview()
@ -186,22 +203,40 @@ public extension ProHUD.Configuration {
}
UIView.animateFastEaseOut(delay: 0, animations: {
UIView.animateForAlert {
vc.imageView?.transform = .identity
vc.view.layoutIfNeeded()
}) { (done) in
}
}
}()
///
lazy var showNavButtons: (ProHUD.Alert) -> Void = {
return { (vc) in
lazy var showNavButtons: (ProHUD.Alert, Alert) -> Void = {
return { (vc, config) in
debugPrint(vc, "showNavButtons")
let btn = UIButton.hideButton()
vc.view.addSubview(btn)
let btn = UIButton.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)
} 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.leading.top.equalTo(vc.contentView).offset(alertConfig.margin/2)
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
debugPrint("点击了隐藏")
@ -213,13 +248,13 @@ public extension ProHUD.Configuration {
///
/// - Parameter callback:
public mutating func loadSubviews(_ callback: @escaping (ProHUD.Alert) -> Void) {
public mutating func loadSubviews(_ callback: @escaping (ProHUD.Alert, Alert) -> Void) {
loadSubviews = callback
}
///
/// - Parameter callback:
public mutating func updateFrame(_ callback: @escaping (ProHUD.Alert) -> Void) {
public mutating func updateFrame(_ callback: @escaping (ProHUD.Alert, Alert) -> Void) {
updateFrame = callback
}

View File

@ -82,15 +82,17 @@ public extension ProHUD {
public func remove() {
let window = hud.getAlertWindow(self)
hud.removeItemFromArray(alert: self)
animateOut { (done) in
UIView.animateForAlertBuildOut(animations: {
self.view.alpha = 0
self.view.transform = .init(scaleX: 1.08, y: 1.08)
}) { (done) in
self.view.removeFromSuperview()
self.removeFromParent()
}
// hide window
let count = hud.alerts.count
if count == 0 && hud.alertWindow != nil {
UIView.animateFastEaseOut(delay: 0, animations: {
self.view.transform = .init(scaleX: 1.05, y: 1.05)
UIView.animateForAlertBuildOut(animations: {
window.backgroundColor = window.backgroundColor?.withAlphaComponent(0)
}) { (done) in
hud.alertWindow = nil
@ -157,7 +159,7 @@ public extension ProHUD {
vm.message = message
vm.scene = scene
vm.icon = icon
alertConfig.updateFrame(self)
alertConfig.updateFrame(self, alertConfig)
return self
}
@ -183,9 +185,8 @@ public extension ProHUD {
addTouchUpAction(for: btn, action: ac)
}
}
UIView.animateFastEaseOut(delay: 0, animations: {
UIView.animateForAlert {
self.view.layoutIfNeeded()
}) { (done) in
}
return self
}
@ -200,9 +201,8 @@ public extension ProHUD {
} else if index < self.actionStack.arrangedSubviews.count, let btn = self.actionStack.arrangedSubviews[index] as? UIButton {
btn.removeFromSuperview()
}
UIView.animateFastEaseOut(delay: 0, animations: {
UIView.animateForAlert {
self.view.layoutIfNeeded()
}) { (done) in
}
return self
}
@ -221,8 +221,8 @@ fileprivate extension ProHUD.Alert {
willLayout = DispatchWorkItem(block: { [weak self] in
if let a = self {
//
alertConfig.loadSubviews(a)
alertConfig.updateFrame(a)
alertConfig.loadSubviews(a, alertConfig)
alertConfig.updateFrame(a, alertConfig)
//
if let t = a.timeout, t > 0 {
a.timeoutBlock = DispatchWorkItem(block: { [weak self] in
@ -236,7 +236,7 @@ fileprivate extension ProHUD.Alert {
if alertConfig.minimizeTimeout > 0 && self?.actionStack.superview == nil {
a.showNavButtonsBlock = DispatchWorkItem(block: { [weak self] in
if let s = self {
alertConfig.showNavButtons(s)
alertConfig.showNavButtons(s, alertConfig)
}
})
DispatchQueue.main.asyncAfter(deadline: .now()+alertConfig.minimizeTimeout, execute: a.showNavButtonsBlock!)
@ -260,15 +260,13 @@ public extension ProHUD {
window.makeKeyAndVisible()
window.resignKey()
window.addSubview(alert.view)
UIView.animateFastEaseOut(delay: 0, animations: {
window.backgroundColor = window.backgroundColor?.withAlphaComponent(0.6)
})
alert.view.transform = .init(scaleX: 1.2, y: 1.2)
alert.view.alpha = 0
UIView.animateFastEaseOut(delay: 0, animations: {
UIView.animateForAlertBuildIn {
alert.view.transform = .identity
alert.view.alpha = 1
})
window.backgroundColor = window.backgroundColor?.withAlphaComponent(0.6)
}
alerts.append(alert)
updateAlertsLayout()
// setup timeout
@ -345,7 +343,7 @@ internal extension ProHUD {
func updateAlertsLayout() {
for (i, a) in alerts.reversed().enumerated() {
let scale = CGFloat(pow(0.7, CGFloat(i)))
UIView.animate(withDuration: 2, delay: 0, usingSpringWithDamping: 1, initialSpringVelocity: 0.5, options: [.allowUserInteraction, .curveEaseInOut], animations: {
UIView.animate(withDuration: 1.8, delay: 0, usingSpringWithDamping: 1, initialSpringVelocity: 0.5, options: [.allowUserInteraction, .curveEaseInOut], animations: {
let y = -50 * CGFloat(i) * CGFloat(pow(0.8, CGFloat(i)))
a.view.transform = CGAffineTransform.init(translationX: 0, y: y).scaledBy(x: scale, y: scale)
}) { (done) in

View File

@ -14,22 +14,7 @@ public extension ProHUD.Alert {
}
extension UIButton {
class func hideButton() -> UIButton {
let btn = UIButton(type: .custom)
btn.contentEdgeInsets = .init(top: 8, left: 8, bottom: 8, right: 8)
btn.setImage(ProHUD.image(named: "ProHUDMinimize"), for: .normal)
btn.layer.shadowOpacity = 0.15
btn.layer.shadowOffset = .init(width: 0, height: 1.2)
btn.layer.shadowRadius = 1.2
btn.alpha = 0
btn.transform = .init(scaleX: 0.5, y: 0.5)
UIView.animateFastEaseOut(delay: 0, animations: {
btn.alpha = 1
btn.transform = .identity
}) { (done) in
}
return btn
}
class func actionButton(style: UIAlertAction.Style, title: String?) -> UIButton {
let btn = UIButton(type: .system)
btn.setTitle(title, for: .normal)
@ -49,7 +34,7 @@ extension UIButton {
}
switch style {
case .default:
setTitleColor(tintColor, for: .normal)
setTitleColor(alertConfig.tintColor, for: .normal)
case .destructive:
setTitleColor(.init(red: 244/255, green: 67/255, blue: 54/255, alpha: 1), for: .normal)
case .cancel:
@ -60,4 +45,22 @@ extension UIButton {
tag = style.rawValue
}
class func minimizeButton() -> UIButton {
let btn = UIButton(type: .system)
// btn.contentEdgeInsets = .init(top: 8, left: 8, bottom: 8, right: 8)
let pd = alertConfig.padding/2
btn.contentEdgeInsets = .init(top: pd*1.5, left: pd*1.5, bottom: pd*1.5, right: pd*1.5)
// btn.imageEdgeInsets.left = pd*0.75
btn.imageEdgeInsets.right = pd*1.5
// btn.setImage(ProHUD.image(named: "ProHUDMinimize"), for: .normal)
// btn.layer.shadowOpacity = 0.15
// btn.layer.shadowOffset = .init(width: 0, height: 1.2)
// btn.layer.shadowRadius = 1.2
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
return btn
}
}

View File

@ -11,7 +11,7 @@ import SnapKit
public extension ProHUD.Configuration {
struct Guard {
/// iPad
public var maxWidth = CGFloat(500)
public var maxWidth = CGFloat(556)
///
public var titleFont = UIFont.boldSystemFont(ofSize: 18)
///

View File

@ -48,13 +48,13 @@ public class HUDController: UIViewController {
internal extension HUDController {
func animateOut(completion: ((Bool) -> Void)? = nil) {
UIView.animateFastEaseOut(delay: 0, animations: {
self.view.alpha = 0
}) { (done) in
completion?(done)
}
}
// 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)

View File

@ -74,12 +74,18 @@ internal extension UIView {
animate(withDuration: duration, delay: delay, usingSpringWithDamping: 1, initialSpringVelocity: 1, options: [.allowUserInteraction, .curveEaseOut], animations: animations, completion: completion)
}
class func animateFastEaseOut(delay: TimeInterval = 0, animations: @escaping () -> Void, completion: ((Bool) -> Void)? = nil) {
animateEaseOut(duration: 0.5, delay: delay, animations: animations, completion: completion)
class func animateForAlertBuildIn(animations: @escaping () -> Void) {
animateEaseOut(duration: 0.8, delay: 0, animations: animations, completion: nil)
}
class func animateForAlertBuildOut(animations: @escaping () -> Void, completion: ((Bool) -> Void)? = nil) {
animateEaseOut(duration: 0.38, delay: 0, animations: animations, completion: completion)
}
class func animateForAlert(animations: @escaping () -> Void) {
animateEaseOut(duration: 1, delay: 0, animations: animations, completion: nil)
}
class func animateSlowEaseOut(delay: TimeInterval = 0, animations: @escaping () -> Void, completion: ((Bool) -> Void)? = nil) {
animateEaseOut(duration: 2, delay: delay, animations: animations, completion: completion)
class func animateForAlert(animations: @escaping () -> Void, completion: ((Bool) -> Void)? = nil) {
animateEaseOut(duration: 1, delay: 0, animations: animations, completion: completion)
}
class func animateForToast(animations: @escaping () -> Void) {

View File

@ -18,5 +18,8 @@
"info" : {
"version" : 1,
"author" : "xcode"
},
"properties" : {
"template-rendering-intent" : "original"
}
}

View File

@ -11,7 +11,7 @@ import SnapKit
public extension ProHUD.Configuration {
struct Toast {
/// iPad
public var maxWidth = CGFloat(500)
public var maxWidth = CGFloat(556)
///
public var titleFont = UIFont.boldSystemFont(ofSize: 18)
///