diff --git a/PHDemo/PHDemo/Extensions.swift b/PHDemo/PHDemo/Extensions.swift
index 2309db6..290454b 100644
--- a/PHDemo/PHDemo/Extensions.swift
+++ b/PHDemo/PHDemo/Extensions.swift
@@ -51,10 +51,8 @@ extension CALayer {
var cornerRadiusWithContinuous: CGFloat {
set {
cornerRadius = newValue
- if #available(iOS 13.0, *) {
+ if cornerCurve != .continuous {
cornerCurve = .continuous
- } else {
- // Fallback on earlier versions
}
}
get { cornerRadius }
diff --git a/PHDemo/PHDemo/Info.plist b/PHDemo/PHDemo/Info.plist
index dd3c9af..8963569 100644
--- a/PHDemo/PHDemo/Info.plist
+++ b/PHDemo/PHDemo/Info.plist
@@ -5,7 +5,7 @@
UIApplicationSceneManifest
UIApplicationSupportsMultipleScenes
-
+
UISceneConfigurations
UIWindowSceneSessionRoleApplication
diff --git a/PHDemo/PHDemo/ListVC.swift b/PHDemo/PHDemo/ListVC.swift
index 5b199d7..d83938a 100644
--- a/PHDemo/PHDemo/ListVC.swift
+++ b/PHDemo/PHDemo/ListVC.swift
@@ -6,6 +6,7 @@
//
import UIKit
+import ProHUD
class ListVC: UITableViewController {
@@ -46,6 +47,7 @@ class ListVC: UITableViewController {
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath, animated: true)
+ AppContext.workspace = self
list.sections[indexPath.section].rows[indexPath.row].action()
}
diff --git a/Package.swift b/Package.swift
index 1a5bea2..2ad0476 100644
--- a/Package.swift
+++ b/Package.swift
@@ -4,7 +4,7 @@ import PackageDescription
let package = Package(
name: "ProHUD",
- platforms: [.iOS(.v10)],
+ platforms: [.iOS(.v13)],
products: [
.library(name: "ProHUD", targets: ["ProHUD"]),
],
diff --git a/Sources/ProHUD/Alert/AlertDefaultLayout.swift b/Sources/ProHUD/Alert/AlertDefaultLayout.swift
index 9e35489..f8286d8 100644
--- a/Sources/ProHUD/Alert/AlertDefaultLayout.swift
+++ b/Sources/ProHUD/Alert/AlertDefaultLayout.swift
@@ -68,7 +68,8 @@ extension Alert: DefaultLayout {
if contentView.superview != view {
view.insertSubview(contentView, at: 0)
}
- if config.enableShadow && AlertWindow.alerts.count > 0 {
+ let alerts = window?.alerts ?? []
+ if config.enableShadow && alerts.count > 0 {
contentView.clipsToBounds = false
contentView.layer.shadowRadius = 4
contentView.layer.shadowOpacity = 0.08
@@ -242,7 +243,8 @@ extension Alert {
public override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
- if config.enableShadow && AlertWindow.alerts.count > 1 {
+ let alerts = window?.alerts ?? []
+ if config.enableShadow && alerts.count > 1 {
contentView.layer.shadowPath = UIBezierPath.init(rect: contentView.bounds).cgPath
}
}
diff --git a/Sources/ProHUD/Alert/AlertManager.swift b/Sources/ProHUD/Alert/AlertManager.swift
index b71f0a1..ec07a4e 100644
--- a/Sources/ProHUD/Alert/AlertManager.swift
+++ b/Sources/ProHUD/Alert/AlertManager.swift
@@ -8,12 +8,14 @@
import UIKit
extension Alert: HUD {
-
+ public func push(scene: UIWindowScene?) {
+ push()
+ }
public func push() {
- guard AlertWindow.alerts.contains(self) == false else {
+ let window = createAttachedWindowIfNotExists()
+ guard window.alerts.contains(self) == false else {
return
}
- let window = attachedWindow
view.transform = .init(scaleX: 1.2, y: 1.2)
view.alpha = 0
navEvents[.onViewWillAppear]?(self)
@@ -32,13 +34,13 @@ extension Alert: HUD {
} completion: { done in
self.navEvents[.onViewDidAppear]?(self)
}
- AlertWindow.alerts.append(self)
- Alert.updateAlertsLayout()
+ window.alerts.append(self)
+ Alert.updateAlertsLayout(alerts: window.alerts)
}
public func pop() {
navEvents[.onViewWillDisappear]?(self)
- let window = attachedWindow
+ let window = window ?? createAttachedWindowIfNotExists()
Alert.removeAlert(alert: self)
let duration = config.animateDurationForBuildOut ?? config.animateDurationForBuildOutByDefault
UIView.animateEaseOut(duration: duration) {
@@ -50,13 +52,14 @@ extension Alert: HUD {
self.navEvents[.onViewDidDisappear]?(self)
}
// hide window
- let count = AlertWindow.alerts.count
- if count == 0 && AlertWindow.current != nil {
+ let count = window.alerts.count
+ if count == 0 {
UIView.animateEaseOut(duration: duration) {
window.backgroundView.alpha = 0
} completion: { done in
- if AlertWindow.alerts.count == 0 {
- AlertWindow.current = nil
+ // 此时不能用self.window,因为alert已经释放掉了
+ if window.alerts.count == 0, let scene = window.windowScene {
+ AppContext.alertWindow[scene] = nil
}
}
}
@@ -72,7 +75,7 @@ public extension Alert {
/// - handler: 实例创建代码
static func lazyPush(identifier: String? = nil, file: String = #file, line: Int = #line, handler: @escaping (_ alert: Alert) -> Void, onExists: ((_ alert: Alert) -> Void)? = nil) {
let id = identifier ?? (file + "#\(line)")
- if let vc = AlertWindow.alerts.last(where: { $0.identifier == id }) {
+ if let vc = find(identifier: id).last {
vc.update(handler: onExists ?? handler)
} else {
Alert { alert in
@@ -96,7 +99,7 @@ public extension Alert {
/// - Parameter identifier: 唯一标识符
/// - Returns: HUD实例
@discardableResult static func find(identifier: String, update handler: ((_ alert: Alert) -> Void)? = nil) -> [Alert] {
- let arr = AlertWindow.alerts.filter({ $0.identifier == identifier })
+ let arr = AppContext.alertWindow.values.flatMap({ $0.alerts }).filter({ $0.identifier == identifier })
if let handler = handler {
arr.forEach({ $0.update(handler: handler) })
}
@@ -106,8 +109,8 @@ public extension Alert {
}
fileprivate extension Alert {
- static func updateAlertsLayout() {
- for (i, a) in AlertWindow.alerts.reversed().enumerated() {
+ static func updateAlertsLayout(alerts: [Alert]) {
+ for (i, a) in alerts.reversed().enumerated() {
let scale = CGFloat(pow(0.9, CGFloat(i)))
UIView.animate(withDuration: 1.8, delay: 0, usingSpringWithDamping: 1, initialSpringVelocity: 0.5, options: [.allowUserInteraction, .curveEaseInOut], animations: {
let y = 0 - a.config.stackDepth * CGFloat(i) * CGFloat(pow(0.85, CGFloat(i)))
@@ -118,25 +121,29 @@ fileprivate extension Alert {
}
}
- var attachedWindow: AlertWindow {
- AlertWindow.attachedWindow(config: config)
+ func createAttachedWindowIfNotExists() -> AlertWindow {
+ AlertWindow.createAttachedWindowIfNotExists(config: config)
}
static func removeAlert(alert: Alert) {
- if AlertWindow.alerts.count > 1 {
- for (i, a) in AlertWindow.alerts.enumerated() {
+ guard var alerts = alert.window?.alerts else {
+ return
+ }
+ if alerts.count > 1 {
+ for (i, a) in alerts.enumerated() {
if a == alert {
- if i < AlertWindow.alerts.count {
- AlertWindow.alerts.remove(at: i)
+ if i < alerts.count {
+ alerts.remove(at: i)
}
}
}
- updateAlertsLayout()
- } else if AlertWindow.alerts.count == 1 {
- AlertWindow.alerts.removeAll()
+ updateAlertsLayout(alerts: alerts)
+ } else if alerts.count == 1 {
+ alerts.removeAll()
} else {
print("‼️代码漏洞:已经没有alert了")
}
+ alert.window?.alerts = alerts
}
}
diff --git a/Sources/ProHUD/Alert/AlertWindow.swift b/Sources/ProHUD/Alert/AlertWindow.swift
index 3a144a7..29e43e6 100644
--- a/Sources/ProHUD/Alert/AlertWindow.swift
+++ b/Sources/ProHUD/Alert/AlertWindow.swift
@@ -7,29 +7,43 @@
import UIKit
+extension Alert {
+ var window: AlertWindow? {
+ get {
+ guard let windowScene = windowScene else {
+ return nil
+ }
+ return AppContext.alertWindow[windowScene]
+ }
+ set {
+ guard let windowScene = windowScene else {
+ return
+ }
+ AppContext.alertWindow[windowScene] = newValue
+ }
+ }
+}
+
class AlertWindow: Window {
- static var current: AlertWindow?
-
- static var alerts = [Alert]()
+ var alerts: [Alert] = []
override var usingBackground: Bool { true }
- static func attachedWindow(config: Configuration) -> AlertWindow {
- if let w = AlertWindow.current {
+ static func createAttachedWindowIfNotExists(config: Configuration) -> AlertWindow {
+ let windowScene = AppContext.windowScene
+ if let windowScene = windowScene, let w = AppContext.alertWindow[windowScene] {
return w
}
let w: AlertWindow
- if #available(iOS 13.0, *) {
- if let scene = AppContext.windowScene {
- w = .init(windowScene: scene)
- } else {
- w = .init(frame: AppContext.appBounds)
- }
+ if let scene = windowScene {
+ w = .init(windowScene: scene)
} else {
w = .init(frame: AppContext.appBounds)
}
- AlertWindow.current = w
+ if let windowScene = windowScene {
+ AppContext.alertWindow[windowScene] = w
+ }
// 比原生alert层级低一点
w.windowLevel = .init(rawValue: UIWindow.Level.alert.rawValue - 1)
return w
diff --git a/Sources/ProHUD/Core/Models/Configuration.swift b/Sources/ProHUD/Core/Models/Configuration.swift
index 7919937..c9c46f3 100644
--- a/Sources/ProHUD/Core/Models/Configuration.swift
+++ b/Sources/ProHUD/Core/Models/Configuration.swift
@@ -13,36 +13,26 @@ public class Configuration: NSObject {
public static var enablePrint = true
public lazy var dynamicBackgroundColor: UIColor = {
- if #available(iOS 13.0, *) {
- let color = UIColor { (traitCollection: UITraitCollection) -> UIColor in
- if traitCollection.userInterfaceStyle == .dark {
- return .init(white: 0.15, alpha: 1)
- } else {
- return .init(white: 1, alpha: 1)
- }
- }
- return color
+ let color = UIColor { (traitCollection: UITraitCollection) -> UIColor in
+ if traitCollection.userInterfaceStyle == .dark {
+ return .init(white: 0.15, alpha: 1)
} else {
- // Fallback on earlier versions
+ return .init(white: 1, alpha: 1)
+ }
}
- return .init(white: 1, alpha: 1)
+ return color
}()
/// 动态颜色(适配iOS13)
public lazy var dynamicTextColor: UIColor = {
- if #available(iOS 13.0, *) {
- let color = UIColor { (traitCollection: UITraitCollection) -> UIColor in
- if traitCollection.userInterfaceStyle == .dark {
- return .init(white: 1, alpha: 1)
- } else {
- return .init(white: 0.1, alpha: 1)
- }
+ let color = UIColor { (traitCollection: UITraitCollection) -> UIColor in
+ if traitCollection.userInterfaceStyle == .dark {
+ return .init(white: 1, alpha: 1)
+ } else {
+ return .init(white: 0.1, alpha: 1)
}
- return color
- } else {
- // Fallback on earlier versions
}
- return .init(white: 0.1, alpha: 1)
+ return color
}()
/// 主标签文本颜色
diff --git a/Sources/ProHUD/Core/Protocols/HUD.swift b/Sources/ProHUD/Core/Protocols/HUD.swift
index ba50838..66e5b98 100644
--- a/Sources/ProHUD/Core/Protocols/HUD.swift
+++ b/Sources/ProHUD/Core/Protocols/HUD.swift
@@ -5,9 +5,17 @@
// Created by xaoxuu on 2022/8/29.
//
-import Foundation
+import UIKit
public protocol HUD {
func push()
+ func push(workspace: Workspace?)
func pop()
}
+
+public extension HUD {
+ func push(workspace: Workspace?) {
+ AppContext.workspace = workspace
+ push()
+ }
+}
diff --git a/Sources/ProHUD/Core/Utils/AppContext.swift b/Sources/ProHUD/Core/Utils/AppContext.swift
index 110f8e2..07ca7b5 100644
--- a/Sources/ProHUD/Core/Utils/AppContext.swift
+++ b/Sources/ProHUD/Core/Utils/AppContext.swift
@@ -7,41 +7,85 @@
import UIKit
+public protocol Workspace {}
+
+extension UIWindowScene: Workspace {}
+extension UIView: Workspace {}
+extension UIViewController: Workspace {}
+
+extension Workspace {
+ var windowScene: UIWindowScene? {
+ if let self = self as? UIWindowScene {
+ return self
+ } else if let self = self as? UIWindow {
+ return self.windowScene
+ } else if let self = self as? UIView {
+ return self.window?.windowScene
+ } else if let self = self as? UIViewController {
+ return self.view.window?.windowScene
+ }
+ return nil
+ }
+}
+
public struct AppContext {
- @available(iOS 13.0, *)
private static var storedAppWindowScene: UIWindowScene?
- private static var storedAppWindow: UIWindow?
+ /// 一个scene关联一个toast
+ static var toastWindows: [UIWindowScene: [ToastWindow]] = [:]
+ static var alertWindow: [UIWindowScene: AlertWindow] = [:]
+ static var sheetWindows: [UIWindowScene: [SheetWindow]] = [:]
- private init() {}
+ static var current: AppContext? {
+ guard let windowScene = windowScene else { return nil }
+ if let ctx = allContexts[windowScene] {
+ return ctx
+ } else {
+ let ctx: AppContext = .init(windowScene: windowScene)
+ allContexts[windowScene] = ctx
+ return ctx
+ }
+ }
+ static var allContexts = [UIWindowScene: AppContext]()
+ private let windowScene: UIWindowScene
+
+ private init(windowScene: UIWindowScene) {
+ self.windowScene = windowScene
+ }
+
+ /// 单窗口应用无需设置,多窗口应用需要指定显示到哪个windowScene上
+ /// workspace可以是windowScene/window/view/viewController
+ public static var workspace: Workspace? {
+ get { windowScene }
+ set {
+ windowScene = newValue?.windowScene
+ }
+ }
}
-public extension AppContext {
+extension AppContext {
- @available(iOS 13.0, *)
+ static var foregroundActiveWindowScenes: [UIWindowScene] {
+ return UIApplication.shared.connectedScenes.compactMap({ $0 as? UIWindowScene }).filter({ $0.activationState == .foregroundActive })
+ }
+
+ /// 如果设置了workspace,就是workspace所对应的windowScene,否则就是最后一个打开的应用程序窗口的windowScene
static var windowScene: UIWindowScene? {
set { storedAppWindowScene = newValue }
get {
if let ws = storedAppWindowScene {
return ws
} else {
- return UIApplication.shared.connectedScenes.first(where: { scene in
- guard let ws = scene as? UIWindowScene else { return false }
- return ws.activationState == .foregroundActive
- }) as? UIWindowScene
+ return foregroundActiveWindowScenes.last
}
}
}
/// 所有的窗口
static var windows: [UIWindow] {
- if #available(iOS 13.0, *) {
- return windowScene?.windows ?? UIApplication.shared.windows
- } else {
- return UIApplication.shared.windows
- }
+ windowScene?.windows ?? UIApplication.shared.windows
}
/// 可见的窗口
@@ -51,28 +95,31 @@ public extension AppContext {
/// App主程序窗口
static var appWindow: UIWindow? {
- get {
- if let w = storedAppWindow {
- return w
- } else {
- return visibleWindows.filter { window in
- return "\(type(of: window))" == "UIWindow" && window.windowLevel == .normal
- }.first
- }
- }
- set { storedAppWindow = newValue }
+ visibleWindows.filter { window in
+ return "\(type(of: window))" == "UIWindow" && window.windowLevel == .normal
+ }.first
}
/// App主程序窗口的尺寸
static var appBounds: CGRect {
- if #available(iOS 13.0, *) {
- return appWindow?.bounds ?? UIScreen.main.bounds
- } else {
- return UIScreen.main.bounds
- }
+ appWindow?.bounds ?? UIScreen.main.bounds
}
/// App主程序窗口的安全边距
static var safeAreaInsets: UIEdgeInsets { appWindow?.safeAreaInsets ?? .zero }
}
+
+// MARK: - instance manage
+
+extension AppContext {
+ var sheetWindows: [SheetWindow] {
+ Self.sheetWindows[windowScene] ?? []
+ }
+}
+
+extension AppContext {
+ var toastWindows: [ToastWindow] {
+ Self.toastWindows[windowScene] ?? []
+ }
+}
diff --git a/Sources/ProHUD/Core/Utils/LayerExts.swift b/Sources/ProHUD/Core/Utils/LayerExts.swift
index 9cf4a54..0fe7d95 100644
--- a/Sources/ProHUD/Core/Utils/LayerExts.swift
+++ b/Sources/ProHUD/Core/Utils/LayerExts.swift
@@ -13,10 +13,8 @@ extension CALayer {
var cornerRadiusWithContinuous: CGFloat {
set {
cornerRadius = newValue
- if #available(iOS 13.0, *) {
+ if cornerCurve != .continuous {
cornerCurve = .continuous
- } else {
- // Fallback on earlier versions
}
}
get { cornerRadius }
diff --git a/Sources/ProHUD/Core/Utils/Utils.swift b/Sources/ProHUD/Core/Utils/Utils.swift
index bef98ce..2abc835 100644
--- a/Sources/ProHUD/Core/Utils/Utils.swift
+++ b/Sources/ProHUD/Core/Utils/Utils.swift
@@ -9,11 +9,7 @@ import UIKit
extension UIImage {
public convenience init?(inProHUD named: String) {
- if #available(iOS 13.0, *) {
- self.init(named: named, in: .module, with: .none)
- } else {
- self.init(named: named)
- }
+ self.init(named: named, in: .module, with: .none)
}
}
@@ -24,7 +20,7 @@ internal var isPortrait: Bool {
return true
}
if UIDevice.current.userInterfaceIdiom == .phone {
- if UIApplication.shared.statusBarOrientation.isPortrait {
+ if AppContext.windowScene?.interfaceOrientation.isPortrait == true {
return true
}
}
diff --git a/Sources/ProHUD/Core/Views/Window.swift b/Sources/ProHUD/Core/Views/Window.swift
index 12da8c8..b072e36 100644
--- a/Sources/ProHUD/Core/Views/Window.swift
+++ b/Sources/ProHUD/Core/Views/Window.swift
@@ -41,7 +41,6 @@ class Window: UIWindow {
rootViewController = vc
}
- @available(iOS 13.0, *)
override init(windowScene: UIWindowScene) {
super.init(windowScene: windowScene)
setup()
diff --git a/Sources/ProHUD/Sheet/SheetManager.swift b/Sources/ProHUD/Sheet/SheetManager.swift
index 585b3bf..84ad844 100644
--- a/Sources/ProHUD/Sheet/SheetManager.swift
+++ b/Sources/ProHUD/Sheet/SheetManager.swift
@@ -51,7 +51,7 @@ public extension Sheet {
/// - Parameter identifier: 唯一标识符
/// - Returns: HUD实例
@discardableResult static func find(identifier: String, update handler: ((_ sheet: Sheet) -> Void)? = nil) -> [Sheet] {
- let arr = SheetWindow.windows.compactMap({ $0.sheet }).filter({ $0.identifier == identifier })
+ let arr = AppContext.sheetWindows.values.flatMap({ $0 }).compactMap({ $0.sheet }).filter({ $0.identifier == identifier })
if let handler = handler {
arr.forEach({ $0.update(handler: handler) })
}
diff --git a/Sources/ProHUD/Sheet/SheetWindow.swift b/Sources/ProHUD/Sheet/SheetWindow.swift
index 5f6cc16..ba3f625 100644
--- a/Sources/ProHUD/Sheet/SheetWindow.swift
+++ b/Sources/ProHUD/Sheet/SheetWindow.swift
@@ -1,5 +1,5 @@
//
-// File.swift
+// SheetWindow.swift
//
//
// Created by xaoxuu on 2022/9/8.
@@ -7,20 +7,30 @@
import UIKit
+
+private extension Sheet {
+ func getContextWindows() -> [SheetWindow] {
+ guard let windowScene = windowScene else {
+ return []
+ }
+ return AppContext.sheetWindows[windowScene] ?? []
+ }
+ func setContextWindows(_ windows: [SheetWindow]) {
+ guard let windowScene = windowScene else {
+ return
+ }
+ AppContext.sheetWindows[windowScene] = windows
+ }
+}
+
class SheetWindow: Window {
- static var windows = [SheetWindow]()
-
var sheet: Sheet
init(sheet: Sheet) {
self.sheet = sheet
- if #available(iOS 13.0, *) {
- if let scene = AppContext.windowScene {
- super.init(windowScene: scene)
- } else {
- super.init(frame: AppContext.appBounds)
- }
+ if let scene = AppContext.windowScene {
+ super.init(windowScene: scene)
} else {
super.init(frame: AppContext.appBounds)
}
@@ -36,6 +46,7 @@ class SheetWindow: Window {
static func push(sheet: Sheet) {
let isNew: Bool
let window: SheetWindow
+ var windows = AppContext.current?.sheetWindows ?? []
if let w = windows.first(where: { $0.sheet == sheet }) {
isNew = false
window = w
@@ -46,6 +57,7 @@ class SheetWindow: Window {
window.rootViewController = sheet
if windows.contains(window) == false {
windows.append(window)
+ sheet.setContextWindows(windows)
}
if isNew {
sheet.navEvents[.onViewWillAppear]?(sheet)
@@ -58,6 +70,7 @@ class SheetWindow: Window {
}
static func pop(sheet: Sheet) {
+ var windows = sheet.getContextWindows()
guard let window = windows.first(where: { $0.sheet == sheet }) else {
return
}
@@ -72,6 +85,7 @@ class SheetWindow: Window {
} else {
consolePrint("‼️代码漏洞:已经没有sheet了")
}
+ sheet.setContextWindows(windows)
}
}
}
diff --git a/Sources/ProHUD/Toast/ToastManager.swift b/Sources/ProHUD/Toast/ToastManager.swift
index 569d860..0607fc5 100644
--- a/Sources/ProHUD/Toast/ToastManager.swift
+++ b/Sources/ProHUD/Toast/ToastManager.swift
@@ -51,7 +51,7 @@ public extension Toast {
/// - Parameter identifier: 唯一标识符
/// - Returns: HUD实例
@discardableResult static func find(identifier: String, update handler: ((_ toast: Toast) -> Void)? = nil) -> [Toast] {
- let arr = ToastWindow.windows.compactMap({ $0.toast }).filter({ $0.identifier == identifier })
+ let arr = AppContext.toastWindows.values.flatMap({ $0 }).compactMap({ $0.toast }).filter({ $0.identifier == identifier })
if let handler = handler {
arr.forEach({ $0.update(handler: handler) })
}
diff --git a/Sources/ProHUD/Toast/ToastWindow.swift b/Sources/ProHUD/Toast/ToastWindow.swift
index c6b4dc2..e6d6d2b 100644
--- a/Sources/ProHUD/Toast/ToastWindow.swift
+++ b/Sources/ProHUD/Toast/ToastWindow.swift
@@ -7,10 +7,23 @@
import UIKit
+private extension Toast {
+ func getContextWindows() -> [ToastWindow] {
+ guard let windowScene = windowScene else {
+ return []
+ }
+ return AppContext.toastWindows[windowScene] ?? []
+ }
+ func setContextWindows(_ windows: [ToastWindow]) {
+ guard let windowScene = windowScene else {
+ return
+ }
+ AppContext.toastWindows[windowScene] = windows
+ }
+}
+
class ToastWindow: Window {
- static var windows = [ToastWindow]()
-
var toast: Toast
var maxY = CGFloat(0)
@@ -18,9 +31,7 @@ class ToastWindow: Window {
init(toast: Toast) {
self.toast = toast
super.init(frame: .zero)
- if #available(iOS 13.0, *) {
- windowScene = AppContext.windowScene
- }
+ windowScene = AppContext.windowScene
toast.window = self
windowLevel = .init(rawValue: UIWindow.Level.alert.rawValue + 1000)
layer.shadowRadius = 8
@@ -41,6 +52,7 @@ class ToastWindow: Window {
static func push(toast: Toast) {
let isNew: Bool
let window: ToastWindow
+ var windows = AppContext.current?.toastWindows ?? []
if let w = windows.first(where: { $0.toast == toast }) {
isNew = false
window = w
@@ -64,8 +76,9 @@ class ToastWindow: Window {
window.rootViewController = toast // 此时toast.view.frame.size会自动更新为window.frame.size
if windows.contains(window) == false {
windows.append(window)
+ toast.setContextWindows(windows)
}
- updateToastWindowsLayout()
+ updateToastWindowsLayout(windows: windows)
if isNew {
window.transform = .init(translationX: 0, y: -window.frame.maxY)
UIView.animateEaseOut(duration: config.animateDurationForBuildInByDefault) {
@@ -80,24 +93,26 @@ class ToastWindow: Window {
}
static func pop(toast: Toast) {
+ var windows = toast.getContextWindows()
guard let window = windows.first(where: { $0.toast == toast }) else {
return
}
if windows.count > 1 {
windows.removeAll { $0 == window }
- updateToastWindowsLayout()
+ updateToastWindowsLayout(windows: windows)
} else if windows.count == 1 {
windows.removeAll()
} else {
consolePrint("‼️代码漏洞:已经没有toast了")
}
toast.vm.duration = nil
+ toast.setContextWindows(windows)
UIView.animateEaseOut(duration: toast.config.animateDurationForBuildOutByDefault) {
window.transform = .init(translationX: 0, y: 0-20-window.maxY)
} completion: { done in
- window.toast.view.removeFromSuperview()
- window.toast.removeFromParent()
- window.toast.navEvents[.onViewDidDisappear]?(window.toast)
+ toast.view.removeFromSuperview()
+ toast.removeFromParent()
+ toast.navEvents[.onViewDidDisappear]?(toast)
}
}
@@ -108,7 +123,7 @@ fileprivate var updateToastsLayoutWorkItem: DispatchWorkItem?
fileprivate extension ToastWindow {
- static func setToastWindowsLayout() {
+ static func setToastWindowsLayout(windows: [ToastWindow]) {
for (i, window) in windows.enumerated() {
let config = window.toast.config
var y = window.frame.origin.y
@@ -128,10 +143,10 @@ fileprivate extension ToastWindow {
}
}
- static func updateToastWindowsLayout() {
+ static func updateToastWindowsLayout(windows: [ToastWindow]) {
updateToastsLayoutWorkItem?.cancel()
updateToastsLayoutWorkItem = DispatchWorkItem {
- setToastWindowsLayout()
+ setToastWindowsLayout(windows: windows)
}
DispatchQueue.main.asyncAfter(deadline: .now()+0.001, execute: updateToastsLayoutWorkItem!)
}