iOS SwiftUI应用打开时.fullScreenCover全屏覆盖弹窗闪烁问题求助
你遇到的闪烁是三个原因共同导致的:
loginPresented默认值写死为true,SwiftUI 首屏渲染时会直接读取这个值,先把登录全屏覆盖渲染出来onAppear是视图已经完成首屏渲染、显示到屏幕上之后才会调用的回调,此时再修改loginPresented的值收起覆盖层,自然就会出现先显示再消失的闪烁- 原有逻辑判断写反:已登录的情况下你设置
loginPresented = true,反而会显示登录页,和你的需求冲突
修复方案
方案1:快速适配现有代码
在视图初始化阶段就给loginPresented赋值正确的初始值,搭配onChange监听登录状态变化实时更新,不需要依赖onAppear:
struct HomeView: View { @ObservedObject var fireViewModel = FirebaseViewModel() @State var loginPresented: Bool init() { let vm = FirebaseViewModel() fireViewModel = vm // 初始值直接对应登录状态:未登录才显示登录页 _loginPresented = State(initialValue: !vm.signedIn) } var body: some View { ZStack { VStack { Text("You are already Signed in") Button(action: { fireViewModel.signOut() }, label: { Text("Sign Out") }) } } // 登录状态变化时实时更新登录页显示状态 .onChange(of: fireViewModel.signedIn) { newValue in loginPresented = !newValue } .fullScreenCover(isPresented: $loginPresented, content: LoginView.init) } }
方案2:根视图层级做登录判断(更合理的架构,完全避免闪烁)
不要在HomeView里嵌套登录覆盖层,直接在App根视图根据登录状态决定渲染哪个页面,从根源上避免覆盖层切换的闪烁问题:
// App入口文件 @main struct YourApp: App { // 用@StateObject持有全局ViewModel,保证生命周期稳定 @StateObject var fireViewModel = FirebaseViewModel() var body: some Scene { WindowGroup { Group { if fireViewModel.signedIn { HomeView(fireViewModel: fireViewModel) } else { LoginView(fireViewModel: fireViewModel) } } // 可选:添加过渡动画让切换更顺滑 .animation(.easeInOut, value: fireViewModel.signedIn) } } } // 调整HomeView,接收外部传入的ViewModel,不要重复初始化 struct HomeView: View { @ObservedObject var fireViewModel: FirebaseViewModel var body: some View { VStack { Text("You are already Signed in") Button(action: fireViewModel.signOut) { Text("Sign Out") } } } }
内容的提问来源于stack exchange,提问作者user15560431
相关产品推荐
相关产品推荐

