You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SwiftUI根据布尔值无法正确显示对应视图问题排查

SwiftUI中绑定Sheet导致登录状态变量被重置的问题修复

问题根源

你遇到的核心问题是:SwiftUI的sheet在关闭时会自动将绑定的isPresented布尔值设为false。而你把控制界面切换(welcomeScreen/mapScreen)的isUserLoggedIn变量同时绑定给了sheet的显示状态,这就导致登录后sheet弹出,关闭时isUserLoggedIn被强制改为false,进而让界面错误切回welcomeScreen。

修复方案

1. 单独使用变量控制Sheet显示(最直接的解决办法)

新增一个独立的状态变量专门管理sheet的弹出,不要复用登录状态变量:

struct HomeScreen: View {

   @EnvironmentObject var authenticationViewModel: AuthenticationViewModel
   
   @State private var isUserLoggedIn = false
   @State private var isLoggedInCancelable: AnyCancellable? = nil
   // 新增专门控制sheet的变量
   @State private var showPostLoginSheet = false
   
   // ...

   var body: some View {
        ZStack {
            if isUserLoggedIn {
                mapScreen
            } else {
                welcomeScreen
            }
        }
        .sheet(isPresented: $showPostLoginSheet) {
            // 弹窗内容
        }
        .onAppear {
            isLoggedInCancelable = authenticationViewModel.publisher.sink { loggedIn in
                print("is user logged in: \(loggedIn)")
                isUserLoggedIn = loggedIn
                // 登录成功时触发sheet弹出
                if loggedIn {
                    showPostLoginSheet = true
                }
            }
        }
        // 页面消失时取消订阅,避免内存泄漏
        .onDisappear {
            isLoggedInCancelable?.cancel()
        }
   }

   // ...

}

2. 避免重复弹出Sheet(可选优化)

如果需要仅在用户首次登录时弹出sheet,可以给AuthenticationViewModel添加标记变量:

class AuthenticationViewModel: ObservableObject {
        
    @Published private var listener: AuthStateDidChangeListenerHandle? = nil
    @Published var hasShownPostLoginSheet = false // 新增标记
    
    private let subject = CurrentValueSubject<Bool, Never>(false)
    var publisher: AnyPublisher<Bool, Never> {
        subject.eraseToAnyPublisher()
    }

    func listenToAuthState() {
        listener = Auth.auth().addStateDidChangeListener { [self] _, user in
            subject.send(user != nil)
        }
    }
    
    // ...
}

然后在HomeScreen中添加判断逻辑:

.onChange(of: isUserLoggedIn) { newValue in
    if newValue && !authenticationViewModel.hasShownPostLoginSheet {
        showPostLoginSheet = true
        authenticationViewModel.hasShownPostLoginSheet = true
    }
}

核心总结

永远不要将控制界面核心状态的变量(如登录状态)与Sheet的显示变量复用,分开管理两者的状态,就能彻底避免Sheet关闭时修改核心状态的问题。

内容的提问来源于stack exchange,提问作者favs

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.21 15:27:13