问题
The selected row remains grey after navigating back from the detail view. Happening both on simulator and real device, only on iOS 14. Does anyone know how to remove it so it behaves the same as on iOS 13 (doesn't remain selected)? This is the only code in the project. (No other navigation's or anything).
let items = ["item1", "item2"]
struct ContentView: View {
var body: some View {
NavigationView {
VStack {
Text("Hello")
List(items, id: \.self) { item in
NavigationLink(destination: Text(item)) {
Text(item)
}
}
.listStyle(PlainListStyle())
}
}
// .navigationViewStyle(StackNavigationViewStyle()) // didn't solve the problem
}
}
This is how it looks
回答1:
I actually found a workaround with lazystack and then putting the row/cell in an Hstack together with some padding and a divider. But the performance is way worse than with a list.
Edit If you put the list outside of another View (in your example dont embed it in a VStack) it will work fine. So you have to put your list in a separate View-Struct and embed this one in your ContentView. Something like this:
struct ExtractedListView: View {
var listItems:[something]
List(listItems, id: \.self) { item in
NavigationLink(destination: Text(item)) {
Text(item)
}
}
struct ContentView : View {
NavigationView {
VStack {
Text("Hello")
ExtractedListView(listItems: items)
}
}
}
回答2:
I had the same problem as soon as I used StackNavigationViewStyle()
.
The issue resolved itself for me by using DefaultNavigationViewStyle()
.
回答3:
Here is the way I made it work. I have found some very rare cases where there is a bit of a lag for the highlight to disappear, but so far it helped a lot. This example uses the MVVM pattern, hopefully you get the idea.
You can access the underlying UITableView behind the SwiftUI List with this third party library :
https://github.com/siteline/SwiftUI-Introspect
and then you can store the tableView instance, and flush the selection when the table appears and disappears (somehow it worked better to do it in both, as those blocks may execute with a bit of lag depending on how aggressively the user navigates)
List {
// ...
}
.introspectTableView { tableView in
self.viewModel.bindToTableView(tableView)
}
.onAppear(perform: {
self.viewModel.clearTableViewSelection()
})
.onDisappear(perform: {
self.viewModel.clearTableViewSelection()
})
And in the viewModel, here are the functions
func bindToTableView(_ tableView: UITableView) {
self.tableView = tableView
}
func clearTableViewSelection() {
// This is a iOS14 hack that prevents clicked cell background view to remain highlighted when we come back to the screen
if #available(iOS 14, *){
DispatchQueue.main.async {
if let selectedIndexPath = self.tableView?.indexPathForSelectedRow {
self.tableView?.deselectRow(at: selectedIndexPath, animated: false)
if let selectedCell = self.tableView?.cellForRow(at: selectedIndexPath) {
selectedCell.setSelected(false, animated: false)
}
}
}
}
}
回答4:
You can wrap your view like this, it is useful especially if you are using list etc. This solution also gets rid of the caret.
ZStack {
NavigationLink(destination: DestinationView()) {
EmptyView()
}
Rectangle().background(Color(UIColor.systemBackground)).foregroundColor(Color(UIColor.systemBackground))
ViewToClick()
}
回答5:
Here is what worked for me:
@State var selection: Int? = nil
var body: some View {
List {
ForEach(self.model.data, id: \.self) { item in
ZStack {
Button("") {
self.selection = item.id
}
NavigationLink(destination: ItemView(item: item), tag: item.id, selection: self.$selection) {
Spacer()
}.hidden()
ItemRow(item: item)
}
}
}
}
来源:https://stackoverflow.com/questions/64042112/selected-list-rows-background-remains-grey-selected-after-navigating-back-in