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

SwiftUI导航至StatsView时出现循环检测错误求助

问题分析与解决方案

问题根源

你通过@AppStorage("login")布尔值直接切换LoginView的body视图结构,这种方式会导致SwiftUI视图层级剧烈突变,触发循环检测错误——SwiftUI会判定状态变化可能引发视图反复创建/销毁的循环依赖。同时,NavigationView的嵌套使用也会加剧层级混乱。

修复方案

改用SwiftUI官方推荐的导航组件,避免直接在body中切换根视图:

方案1(iOS16+ 推荐)

struct LoginView: View {
    @StateObject var data = DataModel()
    @AppStorage("login") private var login: Bool = false
    @AppStorage("username") private var username: String = ""
    @EnvironmentObject var userAuth: UserAuth
    @State var isDisabled = false

    var body: some View {
        NavigationStack {
            VStack {
                TextField("Username", text: $username)
                    .textFieldStyle(RoundedBorderTextFieldStyle())
                Button("Go") {
                    userAuth.login()
                    login = true
                }
            }
            // 绑定login状态,自动导航到StatsView
            .navigationDestination(isPresented: $login) {
                StatsView(username: username, totalSolved: data.stats?.totalSolved ?? 0)
                    .task {
                        await data.loadStats(name: username)
                    }
            }
        }
    }
}

方案2(兼容iOS15及以下)

struct LoginView: View {
    @StateObject var data = DataModel()
    @AppStorage("login") private var login: Bool = false
    @AppStorage("username") private var username: String = ""
    @EnvironmentObject var userAuth: UserAuth
    @State var isDisabled = false

    var body: some View {
        NavigationView {
            VStack {
                TextField("Username", text: $username)
                    .textFieldStyle(RoundedBorderTextFieldStyle())
                Button("Go") {
                    userAuth.login()
                    login = true
                }
                // 隐藏的导航链接,通过login状态控制跳转
                NavigationLink(
                    "",
                    destination: StatsView(username: username, totalSolved: data.stats?.totalSolved ?? 0)
                        .task { await data.loadStats(name: username) },
                    isActive: $login
                )
                .hidden()
            }
        }
    }
}

额外检查

确保StatsView中没有触发login变为false的反向操作,或者这类操作是单向可控的,避免状态反复切换再次引发循环检测。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 03:50:45