7

This is a very specific issue when using ForEach in a TabView with PageTabViewStyle modifier.

Every time I'm inserting an element at the beginning of my array my app crashes.

I'm getting a

attempt to delete item 11 from section 0 which only contains 11 items before the update

error.

In the canvas it crashes too.

Regular appending at the end works fine, also when I remove the PageTabViewStyle modifier it works.

Let me know if I need to elaborate more or if there are questions.

Update: I seems in iOS 15 this issue has been fixed and my code works. I'm still hoping to find a iOS 14 workaround.

I've reproduced the issue with a simple one page app:

import SwiftUI

struct SwiftUIView: View {

    @State var myArray: [String] = ["C", "D", "E", "F", "G"]

    var body: some View {

        VStack {
            Button("Insert before", action: {
                myArray.insert("A", at: 0)
            })
            TabView {
                ForEach(myArray, id: \.self) { value in
                    Text("\(value)")
                }
            }
            .tabViewStyle(PageTabViewStyle(indexDisplayMode: .never))
        }
    }
}

struct SwiftUIView_Previews: PreviewProvider {
    static var previews: some View {
        SwiftUIView()
    }
}
Marco Boerner
  • 1,243
  • 1
  • 11
  • 34
  • 1
    Does this answer your question? [SwiftUI TabView gives an error message during add/delete the element of CoreData](https://stackoverflow.com/questions/67469940/swiftui-tabview-gives-an-error-message-during-add-delete-the-element-of-coredata) – lorem ipsum Jul 17 '21 at 16:04
  • Look at this https://stackoverflow.com/a/63500070/12299030. – Asperi Jul 17 '21 at 16:53
  • @loremipsum ohh I was hoping there was an answer that works with iOS 14. I'll leave the question open in case someone has a workaround. – Marco Boerner Jul 17 '21 at 17:14
  • @Asperi I tried to use this solution but couldn't get it to work. Could you provide some code how this would work with my example? – Marco Boerner Jul 17 '21 at 17:16
  • 1
    Your example works fine with Xcode 13 / iOS 15 – Asperi Jul 17 '21 at 18:53
  • @Asperi I know, loremipsum pointed that out in another answer. However I was hoping to find a way to make it work with at least iOS 14. I'll update my question though to make clear of that. – Marco Boerner Jul 17 '21 at 19:00

2 Answers2

10

Here is tested workaround for Xcode 12.5 / iOS 14.5.

TabView {
    ForEach(myArray, id: \.self) { value in
        Text("\(value)")
    }
}
.tabViewStyle(PageTabViewStyle(indexDisplayMode: .never))
.id(myArray.count)      // << here !!
Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
Asperi
  • 228,894
  • 20
  • 464
  • 690
0

Had same problem of crashing TabView in PageTabViewStyle for ios 14.4 or lower. It was crashing because my list initially was empty and I was populating list in onAppear. Just changed it to check if list is empty.

if myArray.count > 0{
 TabView {
   ForEach(myArray, id: \.self) { value in
       Text("\(value)")
    }
  }
  .tabViewStyle(PageTabViewStyle(indexDisplayMode: .never))
  .id(myArray.count)      //necessary if array size is changing
}
Deepak Gautam
  • 185
  • 4
  • 11