Edited to remove unneccesary code...
I'm trying to build a view in my app which will display a schedule (for practicing musical instruments). The schedule can have multiple sessions, and each session multiple slots. I am retrieving a 2d array of these slots from Realm and then using a foreach inside another foreach to display each session with its contents. I'm using @EnvironmentObject to access Realm from each view and realm assembles a new [[Slot]] each time any information is changed (which it seems to be doing correctly).
The issue I'm having is that, although it is refreshing the sessions when I add/remove them, it is not updating the contents of each session. Realm is correctly working correctly, but the sub view is not being updated. If I exit and re-enter the ScheduleView it will show correctly again. I have tried various things to get it updating correctly, including changing an @State variable in each view after a delay, but nothing so far has worked and I'm starting to pull my hair out!
struct SessionRow: View {
@State var sessionNumber: Int
@State var session: [Slot]
var delete: () -> Void
var addSlot: () -> Void
@State var refreshToggle = false
var body: some View {
VStack{
HStack{
Text("Session \(sessionNumber + 1)")
Button {
self.delete()
} label: {
Label("", systemImage: "trash")
}
.buttonStyle(PlainButtonStyle())
Button {
self.addSlot()
} label: {
Label("", systemImage: "plus")
}
.buttonStyle(PlainButtonStyle())
}
ForEach(0..<self.session.count, id: \.self) { slotNumber in
SlotRow(slot: self.session[slotNumber], ownPosition: [self.sessionNumber, slotNumber])
}
.onDelete { indexSet in
//
}
}
.onAppear{
print("Session Number: \(sessionNumber) loaded.")
}
}
}
func addSlot(sessionNumber: Int){
DispatchQueue.main.async {
self.realmManager.addSlot(sessionNumber: sessionNumber)
self.refreshToggle.toggle()
schedule = realmManager.schedule
}
}
func deleteSession(at offsets: IndexSet){
DispatchQueue.main.async {
self.realmManager.deleteSession(sessionNumber: Int(offsets.first ?? 0))
schedule = realmManager.schedule
}
}
}
struct SlotRow: View {
//@EnvironmentObject var realmManager: RealmManager
@State var slot: Slot
//@Binding var isPresented: Bool
//@Binding var slotPosition: [Int]
@State var ownPosition: [Int]
// Add position/session to allow editing?
var body: some View {
VStack{
HStack{
Text("Own Position: [\(ownPosition[0]),\(ownPosition[1])]")
}
}
.padding()
.frame(height: 80.0)
.onAppear{
print("Slot \(ownPosition) loaded.")
}
}
func deleteIntervalFromSlot() {
//realmManager.updateSlot(session: ownPosition[0], position: ownPosition[1], interval: nil)
}
}
As you can see I've tried all sorts of hacks to get it to update, and loads of this code is unnecessary and will be removed once I have a solution. I thought I would leave it here to show the sort of things which have been tried.