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
相关产品推荐
相关产品推荐

