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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 12:45:00