Maximilian Enders
Maximilian Enders

Reputation: 23

SwiftUI presentationMode.wrappedValue.dismiss() pops back to root

In my project I'm trying to use the presentationMode.wrappedValue.dismiss() in SwiftUI to pop back to the previous view controller after saving data from a form.

The layout is like this:

Root Controller (with List View) --> List view --> Add New Data When using the dismiss() function it always pops back to the root controller instead of the List View.

Here is my code:

Root View Controller:

NavigationView {
            List {
                Section(header: Text("Sortiert nach \(sortStr)")) {
                        ForEach(dbModel.players) { player in
                            NavigationLink(destination: FeedbackListView(player: player)) {
                                PlayerListItemView(player: player)
                            }
                        }// ForEach
                        .onDelete(perform: delete)
                    }
            } // List
}

FeedbackListView

List {
            ForEach(dbModel.feedbacks) { feedback in
                FeedbackListItemView(feedback: feedback)
            }
            .onDelete(perform: delete)
        }//List
        .listStyle(GroupedListStyle())
        
        .toolbar(content: {
            ToolbarItem(placement: .navigationBarTrailing) {
                HStack(spacing: 16) {
                    
                    NavigationLink(destination: AddNewFeedbackView(forPlayer: player)) {
                        ToolbarPlusButton()
                    }//Add Button
                }
            }
        }) // Toolbar

AddNewFeedbackView

Form {
            Section(header: Text("Feedback für \(forPlayer.fullName)")) {
                TextField("Thema", text: $topic)
            }
            
            Section(header: Text("Inhalt")) {
                TextEditor(text: $coachingCue)
                    .frame(minHeight: 120)
            }
            
            Section(header: Text("Wichtigkeit")) {
                Picker(selection: $rating, label: Text("Wichtigkeit")) {
                    ForEach(0..<pickerContent.count) {
                        Text(self.pickerContent[$0])
                    }
                }//Picker
                .pickerStyle(SegmentedPickerStyle())
            }
            
            Section(header: Text("Datum")) {
                DatePicker("", selection: $date, in: ...Date())
                    .labelsHidden()
            }
            
            Section {
                Button(action: {
                    let secondsDate = date.timeIntervalSince1970
                    let newFeedback = Feedback(id: "", date: secondsDate, player: forPlayer.id!, rating: rating, topic: topic, coachingCue: coachingCue)
                    dbModel.addFeedback(newFeedback)
                    self.presentationMode.wrappedValue.dismiss()
                }) {
                    Text("Save")
                }
            }
        }
        .navigationBarTitle("Neues Feedback", displayMode: .inline)

When tapping the Save-Button I get sent back the Root Controller instead of the FeedbackListView.

Upvotes: 2

Views: 2078

Answers (1)

Martin Metselaar
Martin Metselaar

Reputation: 356

I was experiencing the same thing. The origin in the problem is because the NavigationLink to AddNewFeedbackView is in an ToolbarItem. Why is this a problem? I don't know.

But after knowing this I found the following https://www.hackingwithswift.com/forums/swiftui/unexpected-behaviour-with-toolbar-and-navigation-bar/4893. Here it states that once you put the following navigation view style on your NavigationView it will be solved.

.navigationViewStyle(StackNavigationViewStyle())

So in your example it would result in:

NavigationView {
    List {
        Section(header: Text("Sortiert nach \(sortStr)")) {
            ForEach(dbModel.players) { player in
                NavigationLink(destination: FeedbackListView(player: player)) {
                    PlayerListItemView(player: player)
                }
            } // ForEach
            .onDelete(perform: delete)
        }
    } // List
}
.navigationViewStyle(StackNavigationViewStyle())

Upvotes: 4

Related Questions