Add Lottie global loading overlay and fix stuck loading states.

Replace per-VC activity indicators with a ref-counted GlobalLoadingManager, and resolve duplicate show/hide calls on Profile, Statistics, and Home tabs.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-07-06 17:43:13 +08:00
parent 3b17b7f7f0
commit 39186cfe25
14 changed files with 281 additions and 75 deletions

View 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 }
}
}