У меня есть @FetchRequest для NSManagedObject в swiftUI. Я пытаюсь изменить заголовок первого элемента в основных данных, когда используется переключатель, вызывая onReceive. Это не работает , если полученные результаты используются в MainVC. Чтобы продемонстрировать это, заголовок кнопок навигации - это количество элементов в выбранном результате. В результате создается бесконечный цикл в методе ContentView onRecieve. Если кнопка навигации содержит обычный текст, а не использует что-либо из FetchedResults, тогда петли нет, и все работает как положено. Как вызывается этот цикл, и есть ли лучший способ переключения определенного основного элемента данных?
import SwiftUI
import CoreData
final class ContentVCModel : ObservableObject{
@Published var newToDoItem = String()
@Published var shouldTurnOn = false
func createNewToDoItem(){
let moc = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
let toDoItem = ToDoItem(context: moc)
toDoItem.title = self.newToDoItem
toDoItem.createdAt = Date()
toDoItem.cost = Cost(main: "$\(Int.random(in: 1...99))", tax: "$\(Int.random(in: 1...9))")
toDoItem.isOn = false
ToDoItem.save()
self.newToDoItem = ""
}
}
struct ContentView: View {
@ObservedObject var model = ContentVCModel()
@Environment(\.managedObjectContext) var managedObjectContext
@FetchRequest(fetchRequest: ToDoItem.getAllToDoItems()) var toDoItems : FetchedResults<ToDoItem>
var body: some View {
List{
Section(header : Text("Whats next?")){
Toggle("Toggle Test", isOn: $model.shouldTurnOn)
.onReceive(model.$shouldTurnOn) { (newValue) in
self.toDoItems.first?.title = "\(Int.random(in: 23...3423))"
//infitine loop
}
HStack{
TextField("New Item", text: $model.newToDoItem)
Button(action: {
self.model.createNewToDoItem()
}){
Image(systemName: "plus.circle.fill")
.foregroundColor(self.model.newToDoItem.isEmpty ? .gray : .green)
.imageScale(.large)
}.disabled(self.model.newToDoItem.isEmpty)
}
}.font(.headline)
Section(header: Text("To Do's")){
ForEach(toDoItems) { toDoItem in
ToDoItemView(title: toDoItem.title, createdAt: toDoItem.createdAt.description, cost: toDoItem.cost, isOn: true)
}.onDelete { (indexSet) in
let deleteItem = self.toDoItems[indexSet.first!]
self.managedObjectContext.delete(deleteItem)
ToDoItem.save()
}
}
}
.navigationBarTitle(Text("My List"))
.navigationBarItems(trailing: EditButton())
}
}
struct MainVC : View {
@FetchRequest(fetchRequest: ToDoItem.getAllToDoItems()) var toDoItems : FetchedResults<ToDoItem>
var body: some View {
NavigationView{
NavigationLink(destination: ContentView()) {
Text("\(toDoItems.count)") //Using toDoItems causes this to repeat ex: "\(toDoItems.count)"
}
}
}
}