SwiftUI 选择语言后点击保存无法留存选中状态如何解决
问题原因
- ContentView中的
language是普通存储属性,未添加@State包装器,无法响应值变化刷新UI,也无法将修改同步到子视图 - LanguageView接收的language参数使用了
@State包装,没有和父视图的数据源做双向绑定,子视图对language的修改无法回传给父视图 - LanguageView中冗余声明了
selectedLanguage状态变量,和实际绑定到选择器的language变量逻辑冲突,导致点击保存时没有拿到用户实际选中的值
修复后完整代码
struct ContentView: View { // 添加@State包装器,响应值变化刷新UI @State var language: String? = "US" // 可自行修改默认选中值 var body: some View { NavigationView { HStack { // 跳转时传递绑定的language NavigationLink(destination:LanguageView(language: $language)) { Text("Language") .padding() Spacer() Text(language ?? "") .padding() } } } } } struct LanguageView: View { @Environment(\.presentationMode) var pres // 改用@Binding和父视图的language做双向绑定,移除多余的selectedLanguage变量 @Binding var language: String? var body: some View { VStack { // 绑定当前的language到选择器组件 CustomLanguageView(selectedLanguage: $language) Button(action: { // 选中值已通过Binding实时同步,直接返回即可 pres.wrappedValue.dismiss() }) { Text("Save") .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) Rectangle().fill(Color.gray) .frame( height: 1,alignment: .bottom) } .frame(height:15) } } } 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) } } .onTapGesture { self.selectedLanguage = self.language } } }
补充说明
修复后用户选中语言时,选中值会通过@Binding实时同步到父视图的language属性,点击保存按钮返回上一级后,父视图会自动刷新显示最新选中的语言,再次进入语言选择页也会自动回显之前选中的内容。如果需要持久化存储选中的语言,可在保存时将值写入UserDefaults,页面初始化时从UserDefaults读取赋值即可。
内容的提问来源于stack exchange,提问作者Lucky
相关产品推荐
相关产品推荐

