// // RootView.swift // punchnet // // Created by 安礼成 on 2026/1/19. // import SwiftUI struct AppRootView: View { @Environment(AppContext.self) var appContext: AppContext @State private var updateManager = AppUpdateManager.shared var body: some View { ZStack { // 1. 主要界面容器 // 使用 ZStack 代替 Group,因为它在处理内容对齐和转场重叠时更稳定 ZStack(alignment: .center) { switch appContext.appScene { case .login(username: let username): LoginView(username: username) .id("scene_login") // 显式 ID 确保转场触发 case .logined: NetworkView() .id("scene_logined") case .register: RegisterRootView() .id("scene_register") case .resetPassword: ResetPasswordRootView() .id("scene_reset") } } .transition(.asymmetric( insertion: .move(edge: .trailing).combined(with: .opacity), removal: .move(edge: .leading).combined(with: .opacity) // 修改为 leading 更有“流转”感 )) // 自动更新遮罩层级 if updateManager.showUpdateOverlay, let info = updateManager.updateInfo { updateOverlay(info: info) } } // 4. 统一处理 Scene 切换的动画 .animation(.spring(duration: 0.5), value: appContext.appScene) .animation(.spring(duration: 0.4), value: updateManager.showUpdateOverlay) // 关键:macOS 标准毛玻璃背景 .background(VisualEffectView(material: .hudWindow, blendingMode: .behindWindow)) .task { let checkUpdateResult = await updateManager.checkUpdate(isManual: false) NSLog("[RootView] checkUpdateResult: \(checkUpdateResult)") } } // 将遮罩抽离,保持 body 清爽 @ViewBuilder private func updateOverlay(info: SDLAPIClient.AppUpgradeInfo) -> some View { ZStack { Color.black.opacity(0.4) .ignoresSafeArea() .onTapGesture { if !info.forceUpdate { updateManager.showUpdateOverlay = false } } AppUpdateView(info: info) { updateManager.showUpdateOverlay = false } .clipShape(RoundedRectangle(cornerRadius: 16)) .shadow(color: .black.opacity(0.3), radius: 20) } .transition(.asymmetric( insertion: .scale(scale: 0.9).combined(with: .opacity), removal: .opacity )) .zIndex(100) // 确保更新遮罩永远在最上层 } }