添加 Lottie 全局加载层并修复加载状态卡住问题
This commit is contained in:
74
suixinkan/UI/Loading/GlobalLoadingManager.swift
Normal file
74
suixinkan/UI/Loading/GlobalLoadingManager.swift
Normal file
@ -0,0 +1,74 @@
|
||||
//
|
||||
// GlobalLoadingManager.swift
|
||||
// suixinkan
|
||||
//
|
||||
|
||||
import UIKit
|
||||
|
||||
/// 全局 Loading 管理器,对齐 Android `GlobalLoadingManager`。
|
||||
@MainActor
|
||||
final class GlobalLoadingManager {
|
||||
|
||||
static let shared = GlobalLoadingManager()
|
||||
|
||||
private var loadingCount = 0
|
||||
private weak var hostWindow: UIWindow?
|
||||
private var overlayView: GlobalLoadingOverlayView?
|
||||
|
||||
private init() {}
|
||||
|
||||
/// 当前是否正在展示 Loading。
|
||||
var isShowing: Bool {
|
||||
loadingCount > 0
|
||||
}
|
||||
|
||||
/// 增加 Loading 引用计数并展示遮罩。
|
||||
func show() {
|
||||
loadingCount += 1
|
||||
guard loadingCount == 1 else { return }
|
||||
attachOverlayIfNeeded()
|
||||
overlayView?.present()
|
||||
}
|
||||
|
||||
/// 减少 Loading 引用计数,归零后立即隐藏遮罩。
|
||||
func hide() {
|
||||
guard loadingCount > 0 else { return }
|
||||
loadingCount -= 1
|
||||
guard loadingCount == 0 else { return }
|
||||
overlayView?.dismiss()
|
||||
overlayView?.removeFromSuperview()
|
||||
}
|
||||
|
||||
/// 强制关闭所有 Loading。
|
||||
func hideAll() {
|
||||
loadingCount = 0
|
||||
overlayView?.dismiss()
|
||||
overlayView?.removeFromSuperview()
|
||||
}
|
||||
|
||||
private func attachOverlayIfNeeded() {
|
||||
guard let window = keyWindow else { return }
|
||||
hostWindow = window
|
||||
|
||||
if overlayView == nil {
|
||||
let overlay = GlobalLoadingOverlayView(frame: window.bounds)
|
||||
overlay.autoresizingMask = [.flexibleWidth, .flexibleHeight]
|
||||
overlay.isHidden = true
|
||||
overlayView = overlay
|
||||
}
|
||||
|
||||
guard let overlayView else { return }
|
||||
if overlayView.superview !== window {
|
||||
overlayView.removeFromSuperview()
|
||||
window.addSubview(overlayView)
|
||||
}
|
||||
window.bringSubviewToFront(overlayView)
|
||||
}
|
||||
|
||||
private var keyWindow: UIWindow? {
|
||||
UIApplication.shared.connectedScenes
|
||||
.compactMap { $0 as? UIWindowScene }
|
||||
.flatMap(\.windows)
|
||||
.first { $0.isKeyWindow }
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user