swift - 如何在 SwiftUI 中使用 ForEach 仅更改一个核心数据项的切换?

标签 swift core-data foreach swiftui toggle

如何仅更改列表中的一个切换 没有 subview ?如果我从 ForEach 中的所有内容中提取 subview ,我知道如何使其工作,但是如何在一个 View 上执行此操作?
我不能使用 subview ,因为如果我想从这个 subview 中删除一个项目,我以后会遇到问题。它给了我一些我不知道如何修复的错误,所以我试图在一个没有这个错误的 View 上实现它。
列表的代码非常简单:

import SwiftUI

struct ContentView: View {
    
    @Environment(\.managedObjectContext) var moc
    var fetchRequest: FetchRequest<Item>
    var items: FetchedResults<Item> { fetchRequest.wrappedValue }
    
    @State private var doneStatus : Bool = false
    
    var body: some View {
        
        NavigationView {
            List {
                ForEach(items, id: \.self) {item in
                    HStack {
                        Text("\(item.name ?? "default item name")")
                        
                        Spacer()
                        
                        Toggle(isOn: self.$doneStatus) {
                            Text("Done")
                        }
                        .labelsHidden()
                        .onAppear {
                            self.doneStatus = item.done
                        }
                        .onTapGesture {
                            self.doneStatus.toggle()
                            item.done.toggle()
                            try? self.moc.save()
                        }
                    }
                }
                .onDelete(perform: removeItem)
            }
            .navigationBarTitle("Items")
            .navigationBarItems(
                leading:
                Button(action: {
                    for number in 1...3 {
                        let item = Item(context: self.moc)
                        item.date = Date()
                        item.name = "Item \(number)"
                        item.done = false
                        
                        do {
                            try self.moc.save()
                        }catch{
                            print(error)
                        }
                    }
                }) {
                    Text("Add 3 items")
                }
            )
        }
    }
    
    init() {
        fetchRequest = FetchRequest<Item>(entity: Item.entity(), sortDescriptors: [
            NSSortDescriptor(keyPath: \Item.name, ascending: true)
        ])
    }
    
    func removeItem(at offsets: IndexSet) {
        for offset in offsets {
            let item = items[offset]
            moc.delete(item)
        }
        try? moc.save()
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
        //Test data
        let testItem = Item.init(context: context)
        testItem.date = Date()
        testItem.name = "Item name"
        testItem.done = false
        return ContentView().environment(\.managedObjectContext, context)
    }
}
我正在使用 1 个核心数据实体:项目。具有 3 个属性:日期(Date)、完成( bool )、名称(字符串)。
问题
当我点击一个切换时,所有其他切换也会发生变化。
我找不到使用 Core Data 的解决方案。我想也许我应该使用 .id 而不是 .self?并为我的实体添加另一个属性:id (UUID)。但我试着去做,但失败了。
我将不胜感激任何帮助。

最佳答案

你绑定(bind)了所有Toggle到一个州...所以

  • 删除此
  • //    @State private var doneStatus : Bool = false
    
  • 绑定(bind) Toggle动态到当前迭代 item (注意:.onAppear/.onTapGesture 不再需要)
  • Toggle(isOn: Binding<Bool>(
        get: { item.done },
        set: {
            item.done = $0
            try? self.moc.save()
        })) {
        Text()
    }
    .labelsHidden()
    
    backup

    关于swift - 如何在 SwiftUI 中使用 ForEach 仅更改一个核心数据项的切换?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62608131/

    相关文章:

    ios - 互联网连接丢失时使用自定义 REST API 同步来自核心数据的数据?

    PHP/在查询中插入 foreach

    php - 如何使用两个表laravel从同一数据库中获取数据

    ios - 在 NSUserDefaults 键中保存多个值

    ios - 用于从 coredata 查询字符串的子字符串的谓词

    iphone - 初始化后如何将 NSManagedObject 关联到上下文?

    java - 如何纠正 java 中的 For Each 循环(最终测试的输出不正确)?

    swift - 在 Swift 中将动态 Int 变量从一个类传递到另一个类

    swift - 创建后回调: How to run code immediately after ctor?

    ios - 无法对齐数组中的图像(图集)-SpriteKit