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

SwiftUI点击列表行后如何在详情页展示对应ViewModel对象

解决方案

核心思路

不需要给ViewModel额外添加函数,关键是将用户选中的Model对象直接传递给QuestionView,而不是让QuestionView重新初始化ViewModel(这样会拿到全新的默认数据,无法对应选中项)。同时要确保Model遵循Identifiable协议,让ForEach能正确识别列表元素。


步骤1:让Model遵循Identifiable协议

首先修改Model定义,添加Identifiable协议(确保ForEach可以正确遍历列表):

struct Model: Identifiable {
    let id = UUID() // 自动生成唯一标识
    let sentence: [Word]
    let translation: String
    
    struct Word {
        let syllabe: [String]
    }
}

步骤2:修改ContentView,传递选中的Model到QuestionView

更新NavigationLink的目标视图,把当前循环的sentence对象传进去:

struct ContentView: View {
    let vm = ViewModel()
    
    var body: some View {
        NavigationView{
            List {
                ForEach(vm.sentences) { sentence in                
                    NavigationLink(
                        destination: QuestionView(selectedSentence: sentence), // 传递选中的句子对象
                        label: {                
                            Text(sentence.translation) 
                        })
                }
             }
        }
    }
}

步骤3:修改QuestionView,接收并展示选中的内容

移除QuestionView里自行初始化的ViewModel,改为接收外部传入的selectedSentence,用这个对象展示对应内容:

struct QuestionView: View {    
    let selectedSentence: Model // 接收选中的句子对象
    
    var body: some View {
        VStack{
            // 遍历选中句子的所有Word,逐一展示对应的QuestionDetailImage
            ForEach(selectedSentence.sentence, id: \.syllabe) { word in
                QuestionDetailImage(model: word)
            }
            // 可选:展示句子翻译
            Text(selectedSentence.translation)
                .padding(.top)
                .font(.headline)
        }
        .navigationTitle("Sentence Detail")
    }
}

扩展:如果需要业务逻辑处理

如果后续需要对选中的句子做业务操作(比如标记已学习、保存进度等),可以在ViewModel中添加对应函数,示例:

class ViewModel {
    var sentences:[Model] = [...]
    
    // 示例:标记句子为已学习
    func markAsLearned(_ sentence: Model) {
        if let index = sentences.firstIndex(where: { $0.id == sentence.id }) {
            // 若Model添加了learned属性,可在此更新状态
            // sentences[index].learned = true
        }
    }
}

此时需要在QuestionView中传入共用的ViewModel实例,调用函数:

struct QuestionView: View {    
    let selectedSentence: Model
    let vm: ViewModel // 传入共用的ViewModel
    
    var body: some View {
        VStack{
            // ... 展示内容
            Button("Mark as Learned") {
                vm.markAsLearned(selectedSentence)
            }
            .padding(.top)
        }
    }
}
// 对应ContentView中传递vm:
NavigationLink(
    destination: QuestionView(selectedSentence: sentence, vm: vm),
    label: { Text(sentence.translation) }
)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 09:30:55