Hello everyone, I need to update view with core data values but I'm doing something wrong with @StateObject or @Observedobject or something like this.
Explanation
I have 1 main view called MainView that contains 2 views
TagViewPhone() this view contains a list of buttons, the idea is when you click a button it filters the list of words inside WordView2()
For example if you click Tag ( Colors) Only show the words that have the relation with Tag (Colors)
Problem
In my WordViewModel.getWordsFor(tag:Tag) filters that, and it works but WordView2() never update the view
Core data entities
I have 2 Entities with relation Many to Many
Word : id,text and relation wordToTag with destination Tag and inverse tagToWord
Tag: id,text, and relation tagToWord with destination Word and inverse wordToTag
Views
MainView
struct MainView2: View {
var body: some View {
ZStack{
Color("colorBackground").edgesIgnoringSafeArea(.all)
VStack{
TagViewPhone()
WordView2().padding(.horizontal)
}
}
}
}
WordView2
struct WordView2: View {
@ObservedObject private var wordViewModel = WordViewModel()
var body: some View {
ScrollView(.vertical){
ForEach(wordViewModel.words) { word in
Text(word.text ?? "X")
}
}
}
}
TagViewPhone
struct TagViewPhone: View {
@Environment(\.managedObjectContext) private var viewContext
@FetchRequest(sortDescriptors: [NSSortDescriptor(keyPath: \Tag.text, ascending: true)],animation: .default)
private var tags:FetchedResults<Tag>
@ObservedObject var wordViewModel = WordViewModel()
var body: some View {
ScrollView(.horizontal) {
HStack{
ForEach(tags, id:\.id) {tag in
Button {
wordViewModel.getWordsFor(tag: tag)
} label: {
HStack{
Text(tag.text!).bold()
.padding(.horizontal)
.padding(.vertical,5)
}
}
}
}.padding(.all)
}
}
}
ViewModel
WordViewModel
class WordViewModel: ObservableObject {
@Published var words:[Word] = []
let moc = PersistenceController.shared.container.viewContext // Context
init() {
fetchAllWords()
}
func fetchAllWords() -> Void {
let fetchRequest: NSFetchRequest<Word>
fetchRequest = Word.fetchRequest()
words = try! moc.fetch(fetchRequest)
}
func getWordsFor(tag:Tag){
let request: NSFetchRequest<Word> = Word.fetchRequest()
request.predicate = NSPredicate(format: "ANY wordToTag = %@", tag)
do {
words = try moc.fetch(request)
print (words)
} catch let error{
print("Error fetching songs \(error)")
}
}