Problem with Sidebar navigation and modal view with TCA

In the demo project below if you are on an iPad and select a primary view from the sidebar list, then a detail view from that list and now on the detail view you show the modal view, the detail view is closed and the modal is above the primary view if either another view is inside the navigation view (that would be Text("Choose in menu") or the listStyle modifier is used or the .sheet modifier is used. I would expect the modal to stay on the detail view as called and the detail view be visible after closing the modal independent of those conditions. At least that is the case for the SwiftUI project without TCA.

import ComposableArchitecture
import SwiftUI

struct AppState: Equatable {
  var selectedRowIndex: Int?
}

enum AppAction: Equatable {
  case selectRow(Int)
}

struct AppEnvironment {
  var uuid: () -> UUID

  static let live = Self(
    uuid: UUID.init
  )
}

let appReducer = Reducer<AppState, AppAction, AppEnvironment>.combine(
  .init { state, action, _ in
    switch action {
      case .selectRow(let rowIndex):
        state.selectedRowIndex = rowIndex
        return .none
    }
  }
)

struct Sidebar: View {
  let store: Store<AppState, AppAction>
  @State private var showModal: Bool = false

  var body: some View {
    NavigationView {
      WithViewStore(self.store) { viewStore in
        List {
          ForEach(0..<10) { i in
            NavigationLink(destination: PrimaryView(store: self.store), tag: i, selection: .constant(viewStore.selectedRowIndex)) {
              HStack {
                Text("Row \(i)")
                  .foregroundColor(viewStore.selectedRowIndex != nil && viewStore.selectedRowIndex == i ? Color.red : Color.blue)
                Spacer()
              }
              .contentShape(Rectangle())
              .onTapGesture {
                viewStore.send(.selectRow(i))
              }
            }
          }
        }
// every commented line below results in going back to the primary view when showing a modal on the detail view
//        .listStyle(SidebarListStyle())
//        .sheet(isPresented: $showModal, content: {})
      }
`   //       Text("Choose in menu")`
    }
  }
}

struct PrimaryView: View {
  let store: Store<AppState, AppAction>

  var body: some View {
    WithViewStore(self.store) { viewStore in
      List(1..<10) { i in
        NavigationLink(destination: DetailView(text: "Detail \(viewStore.selectedRowIndex!).\(i)")) {
          Text("Primary \(viewStore.selectedRowIndex!).\(i)")
        }
      }
    }
  }
}

struct DetailView: View {
  @State private var show: Bool = false
  var text = "Detail"

  var body: some View {
    VStack {
      Text(text)
        .padding()
      Button("Show Modal") {
        self.show = true
      }
    }
    .sheet(isPresented: $show, content: {
      Text("Modal")
    })
  }
}

This code runs ok, but if you remove the comment on one of the commented lines above the detail view will disappear when the modal is shown.

Is this a known problem or am I missing something? Thanks in advance.

Terms of Service

Privacy Policy

Cookie Policy