This commit is contained in:
xaoxuu 2019-08-01 20:22:57 +08:00
parent d6e8ae791f
commit b8763cd45f
6 changed files with 118 additions and 67 deletions

View File

@ -41,26 +41,34 @@ class ViewController: UIViewController {
//
// }.addAction(style: .cancel, title: "", action: nil).didDisappear {
// debugPrint("didDisappear")
// }.addAction(style: .cancel, title: 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
// hud.show(a)
// t?.remove()
// }
// a.didMinimize {
// ProHUD.show(toast: .loading, title: "", message: "").didTapped {
// ProHUD.show(toast: .loading, title: "", message: "")
// }
// }
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)
}
}
ProHUD.show(toast: .loading, title: "正在加载", message: "拉升的反馈老实交代分开就撒开了击快乐圣反馈老实交代分开就撒开了击快乐圣")
// ProHUD.show(toast: .loading, title: "", message: "")
// ProHUD.show(toast: .loading, title: "", message: "")
DispatchQueue.main.asyncAfter(deadline: .now()+1) {

View File

@ -68,7 +68,7 @@ public extension ProHUD {
timeout = 2
}
willLayout()
willLayoutSubviews()
}
@ -105,7 +105,7 @@ public extension ProHUD {
/// - Parameter timeout:
@discardableResult public func timeout(_ timeout: TimeInterval?) -> Alert {
self.timeout = timeout
willLayout()
willLayoutSubviews()
return self
}
@ -132,6 +132,7 @@ public extension ProHUD {
self?.remove()
}
}
willLayoutSubviews()
return self
}
@ -213,15 +214,16 @@ public extension ProHUD {
}
fileprivate extension ProHUD.Alert {
func willLayout() {
func willLayoutSubviews() {
willLayout?.cancel()
timeoutBlock?.cancel()
showNavButtonsBlock?.cancel()
willLayout = DispatchWorkItem(block: { [weak self] in
if let a = self {
//
alertConfig.loadSubviews(a)
alertConfig.updateFrame(a)
//
a.timeoutBlock?.cancel()
if let t = a.timeout, t > 0 {
a.timeoutBlock = DispatchWorkItem(block: { [weak self] in
self?.remove()
@ -232,7 +234,6 @@ fileprivate extension ProHUD.Alert {
}
//
if alertConfig.minimizeTimeout > 0 && self?.actionStack.superview == nil {
a.showNavButtonsBlock?.cancel()
a.showNavButtonsBlock = DispatchWorkItem(block: { [weak self] in
if let s = self {
alertConfig.showNavButtons(s)
@ -339,8 +340,7 @@ public extension ProHUD {
}
// MARK: AlertHUD private func
fileprivate extension ProHUD {
internal extension ProHUD {
func updateAlertsLayout() {
for (i, a) in alerts.reversed().enumerated() {
@ -353,6 +353,8 @@ fileprivate extension ProHUD {
}
}
}
}
fileprivate extension ProHUD {
func getAlertWindow(_ vc: UIViewController) -> UIWindow {
if let w = alertWindow {

View File

@ -10,6 +10,29 @@ import UIKit
public extension ProHUD {
class ToastWindow: UIWindow {
var deviceOrientationDidChangeCallback: (() -> Void)?
public override init(frame: CGRect) {
super.init(frame: frame)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
@objc func deviceOrientationDidChange(_ notification: Notification){
DispatchQueue.main.asyncAfter(deadline: .now()+0.5) {
self.deviceOrientationDidChangeCallback?()
}
}
}
class StackContainer: UIStackView {

View File

@ -10,7 +10,7 @@ import UIKit
internal let hud = ProHUD.shared
public class ProHUD: NSObject {
public class ProHUD {
public static let shared = ProHUD()
@ -19,18 +19,14 @@ public class ProHUD: NSObject {
internal var alertWindow: UIWindow?
deinit {
debugPrint(self, "deinit")
}
}
internal extension ProHUD {
class var bundle: Bundle {
var b = Bundle.init(for: ProHUD.self)
static var bundle: Bundle {
var b = Bundle.init(for: ProHUD.Alert.self)
let p = b.path(forResource: "ProHUD", ofType: "bundle")
if let bb = Bundle.init(path: p ?? "") {
b = bb
@ -38,7 +34,7 @@ internal extension ProHUD {
return b
}
class func image(named: String) -> UIImage? {
static func image(named: String) -> UIImage? {
return UIImage.init(named: named, in: bundle, compatibleWith: nil)
}

View File

@ -84,6 +84,7 @@ public extension ProHUD.Configuration {
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)

View File

@ -59,6 +59,7 @@ public extension ProHUD {
///
public var vm = ViewModel()
public var removable = true
internal var tapCallback: (() -> Void)?
@ -262,48 +263,57 @@ fileprivate extension ProHUD.Toast {
// MARK: - AlertHUD public func
public extension ProHUD {
@discardableResult
func show(_ toast: Toast) -> Toast {
let config = toastConfig
let isNew: Bool
if toast.window == nil {
let width = CGFloat.minimum(UIScreen.main.bounds.width - 2*config.margin, config.maxWidth)
let w = UIWindow(frame: .init(x: (UIScreen.main.bounds.width - width) / 2, y: config.margin, width: width, height: 400))
let w = ToastWindow(frame: .zero)
toast.window = w
w.windowLevel = UIWindow.Level(5000)
w.backgroundColor = .clear
w.layer.shadowRadius = 8
w.layer.shadowOffset = .init(width: 0, height: 5)
w.layer.shadowOpacity = 0.2
w.rootViewController = toast
w.isHidden = false
isNew = true
} else {
isNew = false
}
let window = toast.window!
window.isHidden = false
toasts.append(toast)
// background & frame
toast.view.layoutIfNeeded()
//
let width = CGFloat.minimum(UIScreen.main.bounds.width - 2*config.margin, config.maxWidth)
toast.view.frame.size = CGSize(width: width, height: 800)
toast.titleLabel.sizeToFit()
toast.bodyLabel.sizeToFit()
let width = toast.view.frame.width
toast.view.layoutIfNeeded()
//
var height = CGFloat(0)
for v in toast.view.subviews {
height = CGFloat.maximum(v.frame.maxY, height)
}
height += config.padding
toast.backgroundView.frame.size = CGSize(width: width, height: height)
// frame
window.frame = CGRect(x: (UIScreen.main.bounds.width - width) / 2, y: 0, width: width, height: height)
toast.backgroundView.frame.size = window.frame.size
window.insertSubview(toast.backgroundView, at: 0)
window.frame.size.height = height // toast.view.frame.height0
toast.view.frame.size.height = height
window.rootViewController = toast // toast.view.frame.sizewindow.frame.size
// y
if toasts.contains(toast) == false {
toasts.append(toast)
}
updateToastsLayout()
window.transform = .init(translationX: 0, y: -window.frame.maxY)
UIView.animateForToast {
window.transform = .identity
if isNew {
window.transform = .init(translationX: 0, y: -window.frame.maxY)
UIView.animateForToast {
window.transform = .identity
}
} else {
toast.view.layoutIfNeeded()
}
return toast
}
@ -371,33 +381,44 @@ public extension ProHUD {
// MARK: AlertHUD private func
fileprivate extension ProHUD {
fileprivate var willUpdateToastsLayout: DispatchWorkItem?
internal extension ProHUD {
func updateToastsLayout() {
for (i, e) in toasts.enumerated() {
let config = toastConfig
if let window = e.window {
var frame = window.frame
if i == 0 {
if isPortrait {
frame.origin.y = Inspire.shared.screen.updatedSafeAreaInsets.top
func f() {
let top = Inspire.shared.screen.updatedSafeAreaInsets.top
for (i, e) in toasts.enumerated() {
let config = toastConfig
if let window = e.window {
var y = window.frame.origin.y
if i == 0 {
if isPortrait {
y = top
} else {
y = config.margin
}
} else {
frame.origin.y = config.margin
let lastY = toasts[i-1].window?.frame.maxY ?? .zero
y = lastY + config.margin
}
UIView.animateForToast {
e.window?.frame.origin.y = y
}
} else {
let lastY = toasts[i-1].window?.frame.maxY ?? .zero
frame.origin.y = lastY + config.margin
}
UIView.animateForToast(animations: {
e.window?.frame = frame
}) { (done) in
}
}
}
willUpdateToastsLayout?.cancel()
willUpdateToastsLayout = DispatchWorkItem(block: {
f()
})
DispatchQueue.main.asyncAfter(deadline: .now()+0.001, execute: willUpdateToastsLayout!)
}
}
internal extension ProHUD {
func removeItemFromArray(toast: Toast) {
if toasts.count > 1 {
for (i, t) in toasts.enumerated() {