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

SwiftUI单选语言后保存返回上页并展示选中值、记忆选中状态如何实现

实现方案

我们用@AppStorage来持久化存储用户选中的语言,既可以跨页面共享数据,也能保证APP重启/重新进入语言页时自动回显选中项,同时配合页面返回逻辑实现保存后跳转。完整修改后的代码如下:


1. ContentView 代码

struct ContentView: View {
    // 读取持久化存储的选中语言,默认值可自定义
    @AppStorage("selectedLanguage") private var selectedLanguage: String = "未选择"
    var body: some View {
        NavigationView {
            HStack {
                NavigationLink(destination:LanguageView() ) {
                    Text("Language")
                    Spacer()
                    // 直接展示已保存的选中语言
                    Text(selectedLanguage)
                }
            }
            .padding(.horizontal)
        }
    }
}

2. LanguageView 及子组件代码

struct LanguageView: View {
    @AppStorage("selectedLanguage") private var savedLanguage: String = "未选择"
    // 临时存储本次进入页面的选中值,点击保存才会同步到持久化存储
    @State private var tempSelected: String?
    // 用于返回上一级页面
    @Environment(\.dismiss) private var dismiss
    
    var body: some View {
        VStack {
            // 把临时选中值绑定传给子组件,进入页面时自动回显已保存的选项
            CustomLanguageView(selectedLanguage: $tempSelected)
                .onAppear {
                    tempSelected = savedLanguage
                }
            
            Button(action: {
                // 保存选中值到持久化存储
                if let select = tempSelected {
                    savedLanguage = select
                }
                // 返回ContentView
                dismiss()
            })
            {
                Text("保存")
                    .foregroundColor(.black)
            }
            .padding()
            Spacer()
        }
    }
}

struct CustomLanguageView: View {
    var language = ["US", "English", "Mexico", "Canada"]
    // 改为绑定属性,接收父页面传的临时选中值
    @Binding var selectedLanguage: String?
    var body: some View {
        LazyVStack {
            ForEach(language, id: \.self) { item in
                SelectionCell(language: item, selectedLanguage: self.$selectedLanguage)
                    .padding(.trailing,40)
                    .padding(.vertical, 12)
                Rectangle().fill(Color.gray)
                    .frame( height: 1,alignment: .bottom)
            }
        }
        .padding(.horizontal)
    }
}

struct SelectionCell: View {
    let language: String
    @Binding var selectedLanguage: String?
    
    var body: some View {
        HStack {
            Text(language)
            Spacer()
            if language == selectedLanguage {
                Image(systemName: "checkmark")
                    .resizable()
                    .frame(width:20, height: 15)
            }
        }
        .contentShape(Rectangle()) // 扩大点击区域,整行都可触发选中
        .onTapGesture {
            self.selectedLanguage = self.language
        }
    }
}

核心逻辑说明

  • @AppStorage是SwiftUI自带的轻量持久化存储方案,底层基于UserDefaults,存储的值不会随APP重启丢失,刚好满足回显选中项的需求
  • 做了临时选中和持久化存储的分离,用户只有点击保存按钮才会同步选中值到全局存储,未保存直接返回的话选中状态不生效,符合常规设置页交互逻辑
  • 补充了点击区域优化,修复了原代码只有文字区域可点击的问题

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 12:06:07