6
votes

L'arrière-plan de la ligne de liste sélectionnée reste gris (sélectionné) après le retour dans la liste (SwiftUI). iOS14 + Xcode12

La ligne sélectionnée reste grise après le retour de la vue détaillée. Se produit à la fois sur simulateur et sur appareil réel, uniquement sur iOS 14. Est-ce que quelqu'un sait comment le supprimer pour qu'il se comporte de la même manière que sur iOS 13 (ne reste pas sélectionné)? C'est le seul code du projet. (Aucune autre navigation ou quoi que ce soit).

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
    }
}

Voilà à quoi ça ressemble


2 commentaires

Avez-vous trouvé un moyen de contourner le problème? Je regrette d'avoir utilisé SwiftUI pour mon nouveau projet!


C'est ridicule de voir comment Apple casse les choses ... Et c'est une simple liste ... Ce que j'ai fait, c'est d'utiliser List pour iOS13 et d'utiliser LazyVStack sur iOS14. Mais ce serait bien si List fonctionnait également sur iOS14.


5 Réponses :


0
votes

En fait, j'ai trouvé une solution de contournement avec lazystack, puis j'ai mis la ligne / cellule dans un Hstack avec un rembourrage et un diviseur. Mais la performance est bien pire qu'avec une liste.

Modifier Si vous placez la liste en dehors d'une autre vue (dans votre exemple, ne l'incorporez pas dans un VStack), cela fonctionnera correctement. Vous devez donc placer votre liste dans un View-Struct séparé et intégrer celui-ci dans votre ContentView. Quelque chose comme ça:

    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)
    }
  }
}


3 commentaires

J'utilise également LazyVStack mais ce n'est bon que pour ios14. Ce serait bien si Apple corrigeait la liste.


Le pire, c'est que ma version iPad de l'application avait l'air vraiment professionnelle sur iOS13. Je n'ai eu qu'à modifier deux petites choses concernant NavigationViews et Liens. Ça avait l'air vraiment cool. Tellement cool que je l'ai utilisé pour montrer les fonctionnalités impressionnantes de SwuftUI. Maintenant, sur iPad, c'est encore pire que les "Bugs" sur iPhone sous iOS14 ... différentes couleurs quand une cellule est cliquée, tout semble être mis en évidence dans la liste. Je ne sais pas comment ils n'ont pas vérifié si les choses concernant List () et NavigationView / -Link se briseraient sous iOS14. Je suppose que plus de 60% de toutes les applications utilisent des tableaux ...


Toujours le même problème après avoir placé la liste dans sa propre structure View. Si vous pouviez partager un exemple de travail copié à partir de Xcode, je l'apprécierais beaucoup.



0
votes

J'ai eu le même problème dès que j'ai utilisé StackNavigationViewStyle() . Le problème s'est résolu pour moi en utilisant DefaultNavigationViewStyle() .


2 commentaires

n'a pas fonctionné malheureusement


Que faire si vous souhaitez utiliser StackNavigationViewStyle mais que vous ne voulez pas le problème?



0
votes

Voici comment je l'ai fait fonctionner. J'ai trouvé de très rares cas où il y a un peu de retard pour que le point culminant disparaisse, mais jusqu'à présent, cela a beaucoup aidé. Cet exemple utilise le modèle MVVM, j'espère que vous avez l'idée.

Vous pouvez accéder à l'UITableView sous-jacent derrière la liste SwiftUI avec cette bibliothèque tierce:

https://github.com/siteline/SwiftUI-Introspect

et vous pouvez ensuite stocker l'instance tableView et vider la sélection lorsque la table apparaît et disparaît (d'une manière ou d'une autre, il était préférable de le faire dans les deux, car ces blocs peuvent s'exécuter avec un peu de décalage en fonction de l'agressivité de la navigation de l'utilisateur)

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)
                }
                
            }
        }
    }
}

Et dans le viewModel, voici les fonctions

List {
// ...
}
.introspectTableView { tableView in
                         self.viewModel.bindToTableView(tableView)
                      }
.onAppear(perform: {
      self.viewModel.clearTableViewSelection()
})
.onDisappear(perform: {
      self.viewModel.clearTableViewSelection()
})


0 commentaires

0
votes

Vous pouvez envelopper votre vue comme ceci, c'est utile surtout si vous utilisez la liste, etc. Cette solution supprime également le curseur.

ZStack {
     NavigationLink(destination: DestinationView()) {
         EmptyView()
     }

     Rectangle().background(Color(UIColor.systemBackground)).foregroundColor(Color(UIColor.systemBackground))
                    
     ViewToClick()
}


0 commentaires

0
votes

Voici ce qui a fonctionné pour moi:

@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)

            }
            
        }
    }
}


0 commentaires