title: SwiftUI - FatalError: Index Out Of Range when Accepting Sheets that are supposed to decline in count
body: <p>I have a pop-up sheet in a SwiftUI app that is supposed to allow me to accept invitations to any new groups I can belong to - the pop-up sheet is a tab view that allows me to swipe between all my different invitations, and they disappear as I either accept or decline them.</p>
  <p>However, I get a crash in the <code>@main</code> line of my app whenever I accept or decline the final invitation.</p>
  <p>This invitation sheet has a view model with a property that is an array of all my pending invitations. It constructs a tabView with a tab for each of the pending invitations. The sheet view has a &quot;sheetCount&quot; state variable that is supposed to decrease as invitations get accepted, and then dismiss the sheet once the sheet count reaches zero.</p>
  <p>I suspect what is happening is the pending invitations are decreasing to zero before the sheetCount reaches zero, and there's some issue trying to render it with no tabs available, and this is causing the crash. But the crash error seems non-specific:</p>
  <pre><code>2021-11-05 08:59:07.036721-0400 GoalTogether[748:24652] [UICollectionViewRecursion] cv == 0x1052d2800 Disabling recursion trigger logging
  Swift/ContiguousArrayBuffer.swift:580: Fatal error: Index out of range
  2021-11-05 08:59:29.996209-0400 GoalTogether[748:24652] Swift/ContiguousArrayBuffer.swift:580: Fatal error: Index out of range
  </code></pre>
  <p>I'm wondering if there is a better way to construct this code flow so that the sheetCount directly follows the number of pendingInvitations and dismisses the sheet as soon as the last pendingViewModel is removed from the property?</p>
  <p>Here is the pop-up sheet that takes all my <code>pendingInviteViewModels</code> in the <code>groupHubViewModel</code> and constructs the tab view of invitations for each each pending invite.</p>
  <pre><code>struct PendingGroupsSheet: View {
      
      @ObservedObject var groupHubVM: GroupHubViewModel
      
      @State var sheetCount: Int
      
      @Environment(\.presentationMode) var presentationMode
      
      init(groupHubVM: GroupHubViewModel) {
          self.groupHubVM = groupHubVM
          
          self._sheetCount = State(initialValue: groupHubVM.pendingInviteViewModels.count)
      }
      
      var body: some View {
          TabView {
              ForEach(groupHubVM.pendingInviteViewModels) { singleGroupVM in
                  PendingGroupInviteView(singleGroupVM: singleGroupVM, onAcceptDecline: {
                      self.dismissIfEmpty()
                  })
              }
          }.tabViewStyle(PageTabViewStyle())
      }
      
      func dismissIfEmpty() {
          sheetCount -= 1
          if sheetCount &gt; 0 {
              return
          } else {
              self.presentationMode.wrappedValue.dismiss()
          }
      }
  }
  </code></pre>
  <p>The TabView has these pending group invite views, which have buttons for accept and decline:</p>
  <pre><code>                Button(action: {
                      self.onAcceptDecline()
                      do {
                          try singleGroupVM.declineGroupInvitation()
                      } catch {
                          print(error.localizedDescription)
                      }
                  }){
                      Text(&quot;Decline&quot;)
                  }.buttonStyle(RoundedRectangleBlackButtonStyle())
                  .padding()
  </code></pre>
  <p>Either of those buttons is supposed to accept or decline an invitation, which will decrease the number of <code>pendingInviteViewModels</code> within the main <code>groupHubViewModel</code> for this page, using the <code>dismissIfEmpty</code> function within the sheet.</p>
  <p>Once the last one is declined or accepted, the dismissIfEmpty function should be setting the sheetCount to 0, and dismissing the sheet. But I think something is happening where the pendingViewModels must be getting set to 0 or nil before the sheetCount decreases, and then I think that is causing the error.</p>