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

SwiftUI中如何根据用户选择获取指定分类的闪卡数据

解决动态过滤CoreData卡片的方案

步骤1:在EndView中收集用户选择的分类

  • 用@State变量存储用户勾选的cardStatus数组(比如selectedStatuses: [Int])
  • 通过Toggle组件绑定每个分类的勾选状态,维护这个数组

步骤2:跳转时传递选中的分类参数

  • 使用SwiftUI导航组件(NavigationLink或NavigationStack的navigationDestination),将selectedStatuses作为参数传递给FlashcardSetView

步骤3:修改FlashcardSetView实现动态FetchRequest

方式一:直接用动态初始化的@FetchRequest

  • 在FlashcardSetView的初始化方法中,接收selectedStatuses参数
  • 用该参数构建NSPredicate,初始化@FetchRequest,实现动态过滤

方式二:使用ObservableObject管理数据(适合复杂场景)

  • 创建ViewModel类,封装CoreData查询逻辑
  • 在ViewModel中根据传入的selectedStatuses执行动态查询,将结果发布给View

关键代码示例

EndView中收集选择并跳转

struct EndView: View {
    @State private var selectedStatuses: [Int] = []
    @State private var path = NavigationPath()
    
    var body: some View {
        NavigationStack(path: $path) {
            Form {
                // 分类1勾选框
                Toggle("分类1", isOn: Binding(
                    get: { selectedStatuses.contains(1) },
                    set: { isOn in
                        isOn ? selectedStatuses.append(1) : selectedStatuses.removeAll { $0 == 1 }
                    }
                ))
                // 分类2、3、4的Toggle同理
                Toggle("分类2", isOn: Binding(
                    get: { selectedStatuses.contains(2) },
                    set: { isOn in
                        isOn ? selectedStatuses.append(2) : selectedStatuses.removeAll { $0 == 2 }
                    }
                ))
                Toggle("分类3", isOn: Binding(
                    get: { selectedStatuses.contains(3) },
                    set: { isOn in
                        isOn ? selectedStatuses.append(3) : selectedStatuses.removeAll { $0 == 3 }
                    }
                ))
                Toggle("分类4", isOn: Binding(
                    get: { selectedStatuses.contains(4) },
                    set: { isOn in
                        isOn ? selectedStatuses.append(4) : selectedStatuses.removeAll { $0 == 4 }
                    }
                ))
            }
            .navigationTitle("选择学习分类")
            .navigationDestination(for: [Int].self) { statuses in
                FlashcardSetView(selectedStatuses: statuses)
            }
            .toolbar {
                Button("Continue studying") {
                    guard !selectedStatuses.isEmpty else {
                        // 可选:提示用户选择至少一个分类
                        return
                    }
                    path.append(selectedStatuses)
                }
            }
        }
    }
}

FlashcardSetView动态FetchRequest实现

struct FlashcardSetView: View {
    let selectedStatuses: [Int]
    @FetchRequest private var flashcards: FetchedResults<Flashcard>
    
    init(selectedStatuses: [Int]) {
        self.selectedStatuses = selectedStatuses
        // 构建过滤条件:cardStatus在选中的数组中
        let predicate = NSPredicate(format: "cardStatus IN %@", selectedStatuses)
        // 初始化FetchRequest,可添加排序规则
        _flashcards = FetchRequest(
            entity: Flashcard.entity(),
            sortDescriptors: [NSSortDescriptor(keyPath: \Flashcard.createdAt, ascending: true)],
            predicate: predicate
        )
    }
    
    var body: some View {
        if flashcards.isEmpty {
            Text("没有符合条件的卡片")
                .navigationTitle("学习卡片")
        } else {
            List(flashcards) { card in
                VStack(alignment: .leading) {
                    Text(card.question ?? "无问题")
                        .font(.headline)
                    Text(card.answer ?? "无答案")
                        .font(.subheadline)
                        .foregroundColor(.secondary)
                }
            }
            .navigationTitle("学习卡片")
        }
    }
}

注意事项

  • 确保CoreData实体的cardStatus属性类型为Int16或Int,与代码中的类型匹配
  • 若用户未选择任何分类,可添加默认逻辑(如显示提示或加载所有卡片)
  • 若需要支持实时更新(比如其他地方修改了卡片状态),@FetchRequest会自动监听CoreData上下文变化,无需额外处理

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 10:35:28