SwiftUI: Update NavigationView after deletion (iPad)

SwiftUI: Update NavigationView after deletion (iPad)

Questions : SwiftUI: Update NavigationView after deletion (iPad)

794

I want to show the empty view (here: in4codes_swiftui-navigationlink Text(“Please select a person.”)) after the in4codes_swiftui-navigationlink deletion of a row has happend on an iPad.

Currently: The detail view on an iPad will in4codes_swiftui-navigationlink not get updated after the deletion of an in4codes_swiftui-navigationlink item. Expected: Show the empty view after in4codes_swiftui-navigationlink the selected item gets deleted.

struct DetailView: View { var name: String var body: some View { Text("Detail of (name)") } } struct MainView: View { @State private var users = ["Paul", "Taylor", "Adele"] var body: some View { NavigationView { List { ForEach(users, id: .self) { user in NavigationLink(destination: DetailView(name: user)) { Text(user) } } .onDelete(perform: delete) } Text("Please select a person.") } } func delete(at offsets: IndexSet) { users.remove(atOffsets: offsets) } } 

NavigationView example from Hacking With in4codes_swiftui-navigationlink Swift.

In the example below, the detail view is in4codes_swiftui-navigationlink shown correctly after the first launch: here

But after the deletion of a row, the in4codes_swiftui-navigationlink previously selected detail view (here: Paul) in4codes_swiftui-navigationlink is still shown: here

Total Answers 3
24

Answers 1 : of SwiftUI: Update NavigationView after deletion (iPad)

As of iOS 14, deleting an element from a in4codes_swift list in a navigation view does not seem in4codes_swift to be supported.

The NavigationLink type takes an in4codes_swift isActive binding, but that does not work in4codes_swift in the case of deletion. When you in4codes_swift receive the .onDelete callback it is too in4codes_swift late. That NavigationLink is not in the in4codes_swift list anymore and any change to the in4codes_swift binding you passed to it is not going to in4codes_swift have any effect.

The workaround is to pass a binding to in4codes_swift the DetailView with all the elements, so in4codes_swift that it can verify if an element is in4codes_swift present and display some content in4codes_swift accordingly.

struct DetailView: View { var name: String @Binding var users: [String] var body: some View { if users.contains(name) { Text("Detail of (name)") } else { EmptyView() } } } struct MainView: View { @State private var users = ["Paul", "Taylor", "Adele"] var body: some View { NavigationView { List { ForEach(users, id: .self) { user in NavigationLink(destination: DetailView(name: user, users: $users)) { Text(user) } } .onDelete(perform: delete) } } } func delete(at offsets: IndexSet) { users.remove(atOffsets: offsets) } } 

0

4

Answers 2 : of SwiftUI: Update NavigationView after deletion (iPad)

You can use a binding from parent view in4codes_swift to manually trigger re-rendering in4codes_swift (otherwise the child view won’t get in4codes_swift notified):

import SwiftUI struct DetailView: View { var name: String @Binding var notifier: Int @State var deleted: Bool = false var body: some View { Group { if !deleted { Text("Detail of (name)") .onChange(of: notifier, perform: { _ in deleted = true }) } else { Text("Deleted") } } } } struct MainView: View { @State private var users = ["Paul", "Taylor", "Adele"] @State private var deleteNotifier: Int = 0 var body: some View { NavigationView { List { ForEach(users, id: .self) { user in NavigationLink(destination: DetailView(name: user, notifier: $deleteNotifier)) { Text(user) } } .onDelete(perform: delete) } Text("Please select a person.") } } func delete(at offsets: IndexSet) { users.remove(atOffsets: offsets) deleteNotifier += 1 } } 

0

2

Answers 3 : of SwiftUI: Update NavigationView after deletion (iPad)

You can use the second choice for the in4codes_swift list updating: index. That way it will in4codes_swift reinforce the refreshing:

 var body: some View { NavigationView { List { ForEach(users.indices, id: .self) { index in NavigationLink(destination: DetailView(name: self.users[index])) { Text(self.users[index]) } } .onDelete(perform: delete) } Text("Please select a person.") } } 

0