简体   繁体   中英

SwiftUI NavigationView adding extra view onto stack when sheet is dismissed

I have a List with ForEach using a NavigationLink that when tapped displays a detail view. The DetailsView includes a sheet to save the detail information into an array. After the save, the sheet is dismissed but an additional DetailsView is put on the navigation stack, so that I need to tap the back link twice to get back to the listing.

I'm likely doing something incorrect as I'm relatively new to swiftui, but can't determine what.

Three things of interest:

  1. In the ListView, I use.navigationViewStyle(StackNavigationViewStyle()). When removed, the issue goes away but the iPad gets messy for the ListView.

  2. I'm using insert(at: 0) to add data in my array because I want the most recent data at the top of the listing. If I use append instead, the issue does go away. Wanting the most recently saved item at the top of the list, I add a sort, however sorting causes the duplicate issue to reappear.

  3. The issue only seems to occur when selecting the first item created in the list (the last in the array) and then saving a new item into the array.

steps:

  1. click Tap Here First, then tap SAVE, enter a name then click Save.
  2. click tab bar item Saved.
  3. click on the list item from step 1 in the Saved Items listing (nav bar should show "< Saved Items").
  4. click SAVE, enter another name then click Save. At this point, the duplicate view appears with "< Back" as the leading nav bar item, clicking it takes you to the original detail view, then clicking "< Saved Items" takes you to the list view.

What am I doing wrong or what should I be doing better?

xcode 12.4/iOS 14.1

Stripped down code to reproduce:

struct TestModel: Identifiable, Codable {
   private(set) var id: UUID
   var name: String
}

class AppData: ObservableObject {
   @Published var testList = [TestModel]()
}

struct NewView: View {
   var body: some View {
      NavigationView {
         NavigationLink(
            destination: DetailView(item: TestModel(id: UUID(), name: ""))) {
            Text("Tap here first")
         }.navigationBarTitle("Main View", displayMode: .inline)
      }.navigationViewStyle(StackNavigationViewStyle())
   }
}

struct ListView: View {
   @EnvironmentObject var appData: AppData
   
   var body: some View {
      NavigationView {
         List {
            ForEach(appData.testList) { item in
               NavigationLink(destination: DetailView(item: item)) {
                  Text(item.name)
               }
            }
         }
         .navigationBarTitle("Saved Items", displayMode: .inline)
      }
      .navigationViewStyle(StackNavigationViewStyle())  // remove this and issue goes away, but iPad gets "messy".
   }
}

struct DetailView: View {
   @State private var isSaveShowing = false
   @State var item: TestModel
   
   var body: some View {
      ScrollView(.vertical, showsIndicators: false) {
         VStack(alignment: .center, spacing: 20)  {
            Text(item.name)
            Button(action: {
               isSaveShowing = true
            }) {
               Text("Save".uppercased())
            }.sheet(isPresented: $isSaveShowing) {
               SaveView(currentItem: item)
            }
         }
      }
   }
}

struct SaveView: View {
   var currentItem: TestModel
   @State private var name = ""
   @EnvironmentObject var appData: AppData
   @Environment(\.presentationMode) var presentationMode
   
   var body: some View {
      NavigationView {
         Form {
            Section(header: Text("Enter Name ".uppercased())
            ) {
               TextField("Name (required)", text: $name)
            }
         }
         .navigationBarItems(
            trailing: Button(action: {
               // appData.testList.append(TestModel(id: UUID(), name: name))  // using append instead of insert also resolves issue...
               appData.testList.insert(TestModel(id: UUID(), name: name), at: 0)
               presentationMode.wrappedValue.dismiss()
            }) {
               Text("Save")
            }
         )
      }
      .navigationViewStyle(StackNavigationViewStyle())
   }
}

struct ContentView: View {
   var appData = AppData()
   
   var body: some View {
      TabView {
         NewView().tabItem {
            Image(systemName: "rectangle.stack.badge.plus")
            Text("Calculate")
         }
         ListView().tabItem {
            Image(systemName: "tray.and.arrow.down")
            Text("Saved")
         }
      }
      .environmentObject(appData)
   }
}

Apparently, this must have been a bug in SwiftUI. Running the same code using Xcode 12.5 beta 3 with iOS 14.5 the issue no longer occurs.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM