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

取消偏好设置视图时恢复@AppStorage初始值的简便方案

解决方案

最简便的方式是直接利用UserDefaults和初始值快照,避免为每个设置单独维护初始变量:

1. 集中管理设置键

定义所有@AppStorage对应的键名数组,统一维护所有设置项:

private let settingKeys = ["setting1", "setting2", "setting3"] // 新增设置时只需添加对应key

2. 保存初始状态快照

在视图加载完成时,从UserDefaults读取所有设置的当前值,保存为初始状态:

@State private var initialSettingValues: [String: Any] = [:]

// 在视图的body中添加onAppear回调
.onAppear {
    let defaults = UserDefaults.standard
    settingKeys.forEach { key in
        initialSettingValues[key] = defaults.object(forKey: key)
    }
}

3. 实现批量重置逻辑

在reset()方法中,将初始快照的值写回UserDefaults,@AppStorage会自动同步这些变更:

private func reset() {
    let defaults = UserDefaults.standard
    initialSettingValues.forEach { key, value in
        defaults.set(value, forKey: key)
    }
}

完整修改后的代码

struct PreferencesView: View {
    @Environment(\.dismiss) private var dismiss

    @AppStorage("setting1") var setting1: Bool = true
    @AppStorage("setting2") var setting2: Bool = false
    @AppStorage("setting3") var setting3: Bool = false
    // 新增设置时:添加@AppStorage变量 + 将对应key加入settingKeys数组即可
    
    private let settingKeys = ["setting1", "setting2", "setting3"]
    @State private var initialSettingValues: [String: Any] = [:]

    var body: some View {
        NavigationView {
            Form {
                Toggle("Setting 1", isOn: $setting1)
                Toggle("Setting 2", isOn: $setting2)
                Toggle("Setting 3", isOn: $setting3)
            }
            .navigationTitle("Preferences")
            .toolbar {
                ToolbarItem(placement: .navigationBarLeading) {
                    Button("Cancel") {
                        reset()
                        dismiss()
                    }
                }
                ToolbarItem(placement: .navigationBarTrailing) {
                    Button("Save") {
                        dismiss()
                    }
                }
            }
            .onAppear {
                let defaults = UserDefaults.standard
                settingKeys.forEach { key in
                    initialSettingValues[key] = defaults.object(forKey: key)
                }
            }
        }
    }

    private func reset() {
        let defaults = UserDefaults.standard
        initialSettingValues.forEach { key, value in
            defaults.set(value, forKey: key)
        }
    }
}

优势

  • 扩展成本极低:新增设置仅需两步操作,无重复代码
  • 批量处理逻辑,避免手动维护每个设置的初始变量
  • 依托UserDefaults与@AppStorage的自动同步特性,无需手动刷新视图

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 15:15:56