mirror of https://github.com/xaoxuu/ProHUD
update
This commit is contained in:
parent
d6e8ae791f
commit
b8763cd45f
|
@ -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) {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 {
|
||||
|
||||
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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.height会变成0
|
||||
toast.view.frame.size.height = height
|
||||
|
||||
window.rootViewController = toast // 此时toast.view.frame.size会自动更新为window.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() {
|
||||
|
|
Loading…
Reference in New Issue