My problem is with SwiftData not updating the object which is used with @Query. here are my code This is my View which used to show list of books,
struct ReadingView: View {
@Environment(\.modelContext) private var modelContext
@Query(filter: #Predicate<SDBook> { book in
book.status == "reading"
}) var itemsBooks: [SDBook]
@Query var items: [SDBook]
var body: some View {
ScrollView {
LazyVStack {
ForEach(itemsBooks, id: \.id) { value in
ReadingRowView(book: value)
}
}
}
}
}
and from ReadingRowView, i am presenting alert to update the current page in book, but this change is not updating in ReadingView().
Here is the code for ReadingRowView
@Observable
class ReadingBooksModel {
var book: SDBook
init(book: SDBook) {
self.book = book
}
}
struct ReadingRowView: View {
@Environment(\.modelContext) private var modelContext
private var itemModel: ReadingBooksModel
@State var progress = 0.0
@State private var showingAlert = false
@State private var pageRead = ""
@State private var showError = false
init(book: SDBook) {
self.itemModel = ReadingBooksModel(book: book)
}
var body: some View {
HStack {
if let selectedPhotoData = itemModel.book.image, let uiImage = UIImage(data: selectedPhotoData) {
Image(uiImage: uiImage)
.resizable()
//.frame(minWidth: 0, maxWidth: .infinity)
.frame(width: 100, height: 150)
.aspectRatio(contentMode: .fit)
.shadow(color:Color.accentColor, radius: 10)
}
VStack (alignment:.leading){
Text(itemModel.book.name)
HStack (alignment: .center){
ProgressView(value: progress, total: 100.0)
Text("\(String(format: "%.0f", progress)) %")
.font(.system(size: 13))
.fontWeight(.medium)
}.padding(.horizontal, 3)
Button {
showingAlert.toggle()
} label: {
Text("Update Progress")
}
.buttonStyle(ProgressButtonModifier())
}
}
.alert(itemModel.book.name, isPresented: $showingAlert) {
TextField("Page read", text: $pageRead)
.modifier(TextFieldModifier())
.keyboardType(.numberPad)
Button("Submit", action: submit)
} message: {
Text("what is your current page ?")
}
.toast(isPresenting: $showError){
AlertToast(displayMode: .banner(.pop), type: .error(Color.accentColor), title: "Current page should not be more than total number of pages")
}
.padding()
.onAppear(perform: {
progress = getPercentage()
})
.modelContainer(for: [SDBook.self])
}
func getPercentage() -> Double{
return Double((100 * itemModel.book.currentPage) / itemModel.book.numberOfPages)
}
func submit() {
print("You entered \(pageRead)")
if pageRead.toInt() > itemModel.book.numberOfPages {
showError.toggle()
}else{
itemModel.book.currentPage = pageRead.toInt()
showingAlert.toggle()
}
}
}
ObservableReadingRowView'sinitand you should be good