I am having a weird SwiftUI crash that I am not understanding. I have a TabView with a list of 3 images inside of it. I am trying to remove the first image from the list by tapping on the button on the screen, but I get this crash.
'NSInternalInconsistencyException', reason: 'attempt to delete and reload the same index path (<NSIndexPath: 0x968bfe135e5a98d1> {length = 2, path = 0 - 0})' terminating with uncaught exception of type NSException
If I remove the TabView from the code, it works as expected and removes the first item. Here is the minimum amount of code needed to reproduce this crash. I have also created a Git repo of this code here -> https://github.com/cameronhenige/TestCrash Could somebody help me figure out what is going on?
import SwiftUI
struct ContentView: View {
@StateObject var testViewModel = TestViewModel()
var body: some View {
GeometryReader { proxy in
ScrollView {
VStack(alignment: .leading, spacing:0) {
TabView {
ForEach(testViewModel.images, id: \.self) { image in
Image(image)
}
}.tabViewStyle(PageTabViewStyle())
.clipShape(RoundedRectangle(cornerRadius: 15))
.padding()
.frame(width: proxy.size.width, height: proxy.size.height/2.5)
}
Button(action: {
testViewModel.removeFirst()
}) {
Text("Remove first item from list")
}
}
}.frame(maxWidth: .infinity).background(Color.black)
}
}
import Foundation
class TestViewModel: NSObject, ObservableObject {
@Published var images: [String] = ["dog", "cat", "bird"]
func removeFirst() {
images.remove(at: 0)
}
}
TabView {
ForEach(testViewModel.images, id: \.self) { image in
Image(image)
}
}.tabViewStyle(PageTabViewStyle())
.clipShape(RoundedRectangle(cornerRadius: 15))
.padding()
.frame(width: proxy.size.width, height: proxy.size.height/2.5)
.id(testViewModel.images.count)
Adding an id to the TabView fixes this issue!
For more of an explanation of why using .id(_:)
fixed the issue for you, it's because when testViewModel.images.count
changes (AKA the view is now using different data) you are invalidating the view because the ID has changed.
For more on invalidating views and how to fix weird view updates, see the Demystify SwiftUI - WWDC21 talk.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With