Selected list row's background remains grey (selected) after navigating back in List (SwiftUI). iOS14 + Xcode12

陌路散爱 提交于 2020-11-30 07:42:30

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!