It is my understanding that I need both List and ForEach in order to use the .onMove and .onDelete magic that Jason demoed in the webinar that showed this stuff, but I cannot figure out how to actually show the data when wrapping the ForEach in a List.
My Situation
In my view I am using
@ObservedRealmObject var huntlet: Huntlet
My list looks like
Text("Huntlet is called\(huntlet.title)")
Text("Huntlet has \(huntlet.tasks.count) task(s)")
List {
ForEach(huntlet.tasks) { task in
TaskListEditRowView(task: task)
}
}
// Also, just for reference
struct TaskListEditRowView: View {
@ObservedRealmObject var task: Task
var body: some View {
TextField("Task Name", text: $task.title)
.foregroundColor(Color("navy"))
}
}
Note: The first two Text() views in this struct are just to verify that the data is getting there.
My understanding with wrapping the List is that I need to include the Edit environment in order to access the .onDelete and .onMove methods, but that these are on the ForEach.
Some things to note:
I have a custom Edit button that is sending through on the Binding
The Hunt object is Read only, so that shows when the Edit button isn’t pressed
The Huntlet object is Read/Write for the user and then a Realm Trigger/Function updates the Hunt object when the Huntlet object is updated.
The code I was referencing in the first post is in the else statement.
Here’s the whole file:
import SwiftUI
import RealmSwift
struct TaskListView: View {
@ObservedRealmObject var hunt: Hunt
@ObservedRealmObject var huntlet: Huntlet
@Binding var editMode: Bool
var body: some View {
VStack {
if !editMode {
ForEach(hunt.tasks) { task in
TaskCardView(task: task, hunt: hunt)
.padding([.leading, .trailing])
}
} else {
if huntlet.title != "" {
Text("Huntlet is called\(huntlet.title)")
Text("Huntlet has \(huntlet.tasks.count) task(s)")
List {
ForEach(huntlet.tasks) { task in
TaskListEditRowView(task: task)
}
}
}
}
}
}
}
struct TaskListEditRowView: View {
@ObservedRealmObject var task: Task
var body: some View {
TextField("Task Name", text: $task.title)
.font(Font.custom("RedHatDisplay-Bold", size: 14))
.foregroundColor(Color("navy"))
}
}
If this is an iOS application, you do not need the Edit environment modifier for this. Simple having onMove and onDelete will enable their behaviour. However to explicitly show the move handle and delete button, you are meant to use the builtin EditButton now (which I would generally place in a navigation bar).
It’s possible swiftUI doesn’t like the Either result from your if statement. If you remove the if and simply add the edit button, you will likely see different results.
I stripped out everything and tried to just wrap the ForEach in a List and am getting nothing:
struct TaskListView: View {
@ObservedRealmObject var hunt: Hunt
@ObservedRealmObject var huntlet: Huntlet
@Binding var editMode: Bool
var body: some View {
List {
ForEach(hunt.tasks) { task in
TaskCardView(task: task, hunt: hunt)
.padding([.leading, .trailing])
}
}
}
}
Again, commenting out the List wrapper and just using ForEach brings the list elements back.
Also, I tried to use .onMove and .onDelete without using List and there is no swipe function to access the Delete button and no ability to click and drag for moving, so it looks like those actually aren’t enabled without the List wrapper wrapped around the ForEach.
Not sure if I should file a crash report or if I’m just doing something wrong.
UPDATE: It works sometimes. I started making a video to show what happens and if I edit the objects, the crash happens. But if I first add a new task and then interact with the editing, it works.
Instead I updated to Realm Cocoa 1.6 so that I can use the new property wrappers. When I pass in the realm with .environment() and use @ObservedRealmObject or @ObservedResults, it seems to update as needed and removes that need to freeze the lists.
I’m happy that you’ve been able to get a solution to this issue, using the new SwiftUI implementation, so If you have any issues in the future with this or any other realm related crash, do not doubt to contact us.
We’ll keep looking into this issue, as we haven’t been able to reproduce it in our local environment.