fix View
This commit is contained in:
parent
97194e501e
commit
067ac7c092
@ -77,8 +77,6 @@ struct LoginView: View {
|
||||
.padding(.bottom, 20)
|
||||
}
|
||||
.frame(width: 380, height: 520)
|
||||
// 关键:macOS 标准毛玻璃背景
|
||||
.background(VisualEffectView(material: .hudWindow, blendingMode: .behindWindow))
|
||||
.ignoresSafeArea()
|
||||
}
|
||||
|
||||
@ -288,25 +286,6 @@ struct CustomSecureField: View {
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - 1. 基础 UI 组件 (已修正 Material 枚举)
|
||||
struct VisualEffectView: NSViewRepresentable {
|
||||
let material: NSVisualEffectView.Material
|
||||
let blendingMode: NSVisualEffectView.BlendingMode
|
||||
|
||||
func makeNSView(context: Context) -> NSVisualEffectView {
|
||||
let view = NSVisualEffectView()
|
||||
view.material = material
|
||||
view.blendingMode = blendingMode
|
||||
view.state = .active
|
||||
return view
|
||||
}
|
||||
|
||||
func updateNSView(_ nsView: NSVisualEffectView, context: Context) {
|
||||
nsView.material = material
|
||||
nsView.blendingMode = blendingMode
|
||||
}
|
||||
}
|
||||
|
||||
#Preview {
|
||||
LoginView()
|
||||
.environment(AppContext(noticePort: 0))
|
||||
|
||||
@ -14,11 +14,10 @@ struct RegisterRootView: View {
|
||||
|
||||
var body: some View {
|
||||
ZStack {
|
||||
// 背景毛玻璃
|
||||
VisualEffectView(material: .underWindowBackground, blendingMode: .behindWindow)
|
||||
Color.clear
|
||||
.ignoresSafeArea()
|
||||
|
||||
Group {
|
||||
ZStack(alignment: .center) {
|
||||
switch registerModel.stage {
|
||||
case .requestVerifyCode:
|
||||
RegisterRequestVerifyCodeView()
|
||||
@ -64,7 +63,6 @@ struct RegisterRootView: View {
|
||||
.transition(.opacity) // 按钮出现的动画
|
||||
}
|
||||
}
|
||||
.frame(width: 500, height: 400)
|
||||
}
|
||||
}
|
||||
|
||||
@ -122,7 +120,9 @@ struct RegisterRequestVerifyCodeView: View {
|
||||
.frame(width: 280)
|
||||
|
||||
Button(action: {
|
||||
self.requestVerifyCode(username: model.username)
|
||||
Task { @MainActor in
|
||||
await self.requestVerifyCode(username: model.username)
|
||||
}
|
||||
}) {
|
||||
Text("获取验证码")
|
||||
.fontWeight(.medium)
|
||||
@ -141,13 +141,15 @@ struct RegisterRequestVerifyCodeView: View {
|
||||
}
|
||||
}
|
||||
|
||||
private func requestVerifyCode(username: String) {
|
||||
private func requestVerifyCode(username: String) async {
|
||||
self.isProcessing = true
|
||||
Task { @MainActor in
|
||||
defer {
|
||||
self.isProcessing = false
|
||||
}
|
||||
|
||||
if username.isEmpty {
|
||||
self.showAlert = true
|
||||
self.errorMessage = "邮箱为空"
|
||||
self.isProcessing = false
|
||||
return
|
||||
}
|
||||
|
||||
@ -173,8 +175,6 @@ struct RegisterRequestVerifyCodeView: View {
|
||||
self.showAlert = true
|
||||
self.errorMessage = "邮箱格式错误"
|
||||
}
|
||||
self.isProcessing = false
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -14,11 +14,10 @@ struct ResetPasswordRootView: View {
|
||||
|
||||
var body: some View {
|
||||
ZStack {
|
||||
// 背景毛玻璃 (macOS 风格)
|
||||
VisualEffectView(material: .underWindowBackground, blendingMode: .behindWindow)
|
||||
Color.clear
|
||||
.ignoresSafeArea()
|
||||
|
||||
Group {
|
||||
ZStack(alignment: .center) {
|
||||
switch resetPasswordModel.stage {
|
||||
case .requestVerifyCode:
|
||||
GetVerifyCodeView()
|
||||
@ -60,7 +59,6 @@ struct ResetPasswordRootView: View {
|
||||
.transition(.opacity) // 按钮出现的动画
|
||||
}
|
||||
}
|
||||
.frame(width: 500, height: 400)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -9,32 +9,59 @@ import SwiftUI
|
||||
|
||||
struct RootView: View {
|
||||
@Environment(AppContext.self) var appContext: AppContext
|
||||
|
||||
@State private var updateManager = AppUpdateManager.shared
|
||||
|
||||
var body: some View {
|
||||
ZStack {
|
||||
// 主要界面
|
||||
Group {
|
||||
// 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")
|
||||
}
|
||||
}
|
||||
// 2. 关键:设置容器尺寸行为
|
||||
// 如果是全屏应用,用 maxWidth/Height .infinity
|
||||
// 如果是固定大小窗口,可以在这里写死 minWidth/minHeight
|
||||
.frame(maxWidth: .infinity, maxHeight: .infinity)
|
||||
// 3. 限制裁剪,防止位移动画超出 RootView 的边界
|
||||
.clipped()
|
||||
.transition(.asymmetric(
|
||||
insertion: .move(edge: .trailing).combined(with: .opacity),
|
||||
removal: .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 {
|
||||
@ -43,27 +70,19 @@ struct RootView: View {
|
||||
}
|
||||
}
|
||||
|
||||
// 弹窗卡片
|
||||
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) // 确保更新遮罩永远在最上层
|
||||
}
|
||||
}
|
||||
.animation(.spring(duration: 0.4), value: updateManager.showUpdateOverlay)
|
||||
.task {
|
||||
// 启动时静默检查
|
||||
let checkUpdateResult = await updateManager.checkUpdate(isManual: false)
|
||||
NSLog("[RootView] checkUpdateResult: \(checkUpdateResult)")
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#Preview {
|
||||
RootView()
|
||||
|
||||
@ -55,16 +55,7 @@ struct punchnetApp: App {
|
||||
//.interactiveDismissDisabled() // 强制阅读
|
||||
}
|
||||
}
|
||||
// .commands {
|
||||
// CommandGroup(replacing: .appInfo) {
|
||||
// Button {
|
||||
// openWindow(id: "abortPunchnet")
|
||||
// } label: {
|
||||
// Text("About Punchnet")
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//.windowResizability(.contentSize)
|
||||
.windowResizability(.contentSize)
|
||||
.windowToolbarStyle(.unified)
|
||||
.defaultPosition(.center)
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user