I have a List containing ItemRow views based on an ItemDetails object. The content is provided by a model which pulls it from Core Data.
When I scroll through the list one or two of the rows will disappear and reappear when I scroll back up. I have a feeling it's because the state is being lost?
Here's some relevant info (only necessary parts of the files are provided):
-- ModelData.swift:
@Observable
class ModelData {
var allItems: [ItemDetails] = coreData.getAllItems()
...
}
-- ItemDetails.swift:
struct ItemDetails: Identifiable, Hashable, Equatable {
public let id: UUID = UUID()
public var itemId: String // Also unique, but used for a different reason
...
}
-- MainApp.swift:
let modelData: ModelData = ModelData() // Created as a global
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
// Methods in here (and in lots of other places) use `modelData`, which is why it's a global
}
@main
struct MainApp: App {
var body: some Scene {
WindowGroup {
MainView()
}
}
...
}
-- MainView.swift:
struct MainView: View {
var body: some View {
List {
ForEach(modelData.allItems, id: \.id) { item in
ItemRow(item)
}
}
}
}
struct ItemRow: View, Equatable {
var item: ItemDetails
var body: some View {
...
}
static func == (lhs: Self, rhs: Self) -> Bool {
lhs.item == rhs.item
}
}
There's obviously more code in the app than that, but it's not relevant to the issue.
I've tried:
ItemRow(item).equatable()- Wrapping
ItemRowin anEquatableView - Giving the
Lista uniqueid - Using
class ModelData: ObservableObjectand@StateObjectformodelData
None made any difference.
I'm using iOS/iPadOS 26.0.1, and I see it on my physical iPhone 17 Pro Max and iPad Pro 11-inch M4, but I don't see it in the equivalent simulators on those versions. The Simulator also doesn't exhibit this for versions 17.5 and 18.5, and I have no physical devices on 17.5/18.5 to check.
Should I be doing as I currently am, where I create modelData as a global let so I can access it everywhere, or should I pass it through the view hierarchy as an Environment variable, like @Environment(ModelData.self) var modelData: ModelData? Bear in mind that some functions are outside of the view hierarchy and cannot access modelData if I do this. Various things like controllers that need access to values in modelData cannot get to it.
Any ideas? Thanks.
Should I be doing as I currently am, where I create modelData as a global let so I can access it everywhere, or should I pass it through the view hierarchy as an Environment variable, like @Environment(ModelData.self) var modelData: ModelData? Bear in mind that some functions are outside of the view hierarchy and cannot access modelData if I do this. Various things like controllers that need access to values in modelData cannot get to it.
Since It's an observable object, make it a State at the App level and pass that down your view hierarchy using environment modifier. You can also have a singleton instance of ModelData if you only ever need a single instance of the object.
We’ll need more information to fully understand the issue. If you encounter the same problem with the relevant code in a small test project, please share a link to it. This will help us better comprehend the situation. If you’re not familiar with creating a test project, refer to Creating a test project.