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

SwiftUI问题:使用NavigationLink切换视图后复选标记消失

问题:子视图返回后复选框状态丢失

开发带复选标记列表的App时,从子视图返回主视图后再次进入,之前的选择会消失。尝试用UserDefaults保存Toggle状态,但未达到预期效果。

核心问题

所有CheckView实例共用同一个UserDefaults键"locationToggle",导致所有复选框状态互相覆盖;同时@State是视图级状态,子视图销毁后状态会丢失,重新进入时会重置初始值。

解决方案

  1. 为每个复选框生成唯一的UserDefaults键,用CountriesItem的id作为键的一部分,保证每个项目状态独立存储。
  2. 在CheckView初始化时直接从UserDefaults读取初始状态,替代onAppear触发读取,避免视图重建时的状态重置。
  3. 优化计数逻辑,确保仅在状态真正变化时调整计数,避免重复加减。

修改后的代码

CheckView

struct CheckView: View {
    @State private var isChecked: Bool
    @EnvironmentObject var numofitems: NumOfItems
    let itemId: UUID
    
    var title: String
    var count: Int = 0
    
    init(title: String, itemId: UUID) {
        self.title = title
        self.itemId = itemId
        // 初始化时从UserDefaults读取对应项目的状态
        self._isChecked = State(initialValue: UserDefaults.standard.bool(forKey: "toggle_\(itemId.uuidString)"))
    }
    
    var body: some View {
        HStack {
            Toggle(title, isOn: $isChecked)
                .toggleStyle(CheckToggleStyle())
                .tint(.mint)
                .onChange(of: isChecked) { newValue in
                    // 更新对应项目的UserDefaults状态
                    UserDefaults.standard.set(newValue, forKey: "toggle_\(itemId.uuidString)")
                    // 根据状态变化调整计数
                    numofitems.num += newValue ? 1 : -1
                }
            Spacer()
        }
    }
}

主视图 CheckListView

struct CheckListView: View {
    @State private var menu = Bundle.main.decode([ItemsSection].self, from: "items.json")
    
    var body: some View {
        NavigationView {
            List {
                ForEach(menu) { section in
                    NavigationLink(section.name) {
                        ScrollView {
                            ForEach(section.items) { item in
                                // 传入item的id,用于生成唯一存储键
                                CheckView(title: item.name, itemId: item.id)
                            }
                        }
                    }
                }
            }
        }
        .navigationBarHidden(true)
        .navigationViewStyle(StackNavigationViewStyle())
        .listStyle(GroupedListStyle())
    }
}

补充说明

  • 每个复选框的状态通过toggle_\(itemId.uuidString)键单独存储,不会互相干扰。
  • 初始化时直接读取UserDefaults,确保进入子视图时能立即恢复之前的选择状态。
  • 计数逻辑仅在状态切换时触发,避免视图重建导致的重复计数问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 21:45:28