52
votes

Comment modifier la couleur d'arrière-plan d'une liste dans SwiftUI?

J'essaie de recréer une interface utilisateur que j'ai construite avec UIKit dans SwiftUI mais je rencontre quelques problèmes mineurs.

Je veux changer la couleur de la List ici, mais aucune propriété ne semble fonctionner comme prévu. Exemple de code ci-dessous:

struct ListView: View {
    @EnvironmentObject var listData: ListData

       var body: some View {
        NavigationView {
            List(listData.items) { item in
                ListItemCell(item: item)
            }
            .content.background(Color.yellow) // not sure what content is defined as here
            .background(Image("paper-3")) // this is the entire screen 
        }
    }
}

struct ListItemCell: View {
    let item: ListItem

    var body: some View {

        NavigationButton(destination: Text(item.name)) {
            Text("\(item.name) ........................................................................................................................................................................................................")
                .background(Color.red) // not the area I'm looking for
        }.background(Color.blue) // also not the area I'm looking for
    }
}

Je veux changer la zone BLANCHE


14 Réponses :


8
votes

J'ai pu obtenir toute la liste pour changer de couleur en utilisant colorMultiply (Color :). Ajoutez simplement ce modificateur à la fin de la vue de liste, puis le remplissage poussera la table vers les bords de l'appareil. Par exemple:

List {...}.colorMultiply(Color.green).padding(.top)

https://www.hackingwithswift.com/quick-start/swiftui/how-to-adjust-views-by-tinting-and-desaturating-and-more


2 commentaires

Cela fonctionne, mais cela perturbe la couleur des cellules - c'est-à-dire juste essayé avec du texte rouge comme éléments de liste - ils deviennent noirs.


Oui, malheureusement, le mélange n'est pas ce que vous voulez. Vous voulez qu'il soit superposé, avec la couleur de la vue d'arrière-plan comme, eh bien, l'arrière-plan, puis la couleur de la cellule et / ou la couleur du texte en plus de cela



54
votes

Ok, j'ai trouvé la solution pour colorer les lignes de la liste:

List {
    TestRow()
    TestRow()
    TestRow()
}

puis dans le corps:

struct TestRow: View {

    var body: some View {
        Text("This is a row!")
        .listRowBackground(Color.green)
    }
}

Cela fonctionne comme prévu, mais je n'ai pas encore trouvé comment supprimer les lignes de division entre les lignes ...


5 commentaires

SwiftUI est incroyablement bogué en ce moment, cela fonctionne lorsque j'utilise ce code comme celui-ci et que je code en dur mes éléments de liste. Lorsque je charge mes données de manière asynchrone, cela ne fonctionne plus.


Ouais, c'est un peu pénible. C'est amusant de jouer avec, cependant. Devrait être plus lissé bientôt, espérons-le


@MariusWaldal Avez-vous trouvé comment changer la couleur d'arrière-plan de la vue en coupe?


@andromedainiative Do List {ForEach (items, id: \ .self) {item in Text (item) .listRowBackground (Color.green)} à la place, alors ça marche.


J'ai eu ce problème vraiment stupide où le modificateur .listRowBackground () devait être après le modificateur .contextMenu (), sinon cela ne fonctionnerait pas. Xcode 12.0.1



3
votes

Quelqu'un peut trouver cela utile s'il tente de créer une cellule de type flottant avec SwiftUI en utilisant .listRowBackground et en appliquant .padding

var body: some View {
    NavigationView {
        List {
            ForEach (site) { item in
                HStack {
                    Text(String(item.id))

                    VStack(alignment: .leading) {
                        Text(item.name)
                        Text(item.crop[0])
                    }

                }.listRowBackground(Color.yellow)
                      .padding(.trailing, 5)
                      .padding(.leading, 5)
                      .padding(.top, 2)
                      .padding(.bottom, 2))
            }
        }
            .navigationBarTitle(Text("Locations"))
    }
}


3 commentaires

Salut @ caleb81389, Cela fonctionne pour moi mais cela ne s'appliquera pas aux lignes vides. Avez-vous une idée pourquoi?


Non désolé. Je ne sais pas comment appliquer cela aux lignes vides. Peut-être pourriez-vous mettre artificiellement du texte d'espace blanc «» dans une étiquette ou quelque chose comme ça ...? A part ça, SwiftUI fait un peu ce qu'il veut et quelque chose comme ça va prendre quelqu'un que moi pour répondre.


Faites-moi savoir si vous le comprenez!



2
votes

Je suppose que le modificateur listRowPlatterColor devrait le faire, mais ce n'est pas le cas à partir de Xcode 11 Beta 11M336w

var body: some View {
    List(pokemon) { pokemon in
        PokemonCell(pokemon: pokemon)
            .listRowPlatterColor(.green)
    }
}


1 commentaires

listRowPlatterColor est désormais obsolète et ne fonctionne que sur watchOS.



8
votes

Je ne sais pas quelle est la connexion mais si vous enveloppez la liste avec Form cela fonctionne.

Form {
     List(viewModel.currencyList, id: \.self) { currency in
        ItemView(item: currency)
     }
      .listRowBackground(Color("Primary"))
      .background(Color("Primary"))
}


2 commentaires

Comme Caleb le souligne, le listRowBackground ne doit pas être appliqué à la liste mais à l'élément de ligne lui-même. De plus, vous devriez pouvoir simplement faire Color ("Primary") au lieu de forcer le déballage d'un UIColor :)


Cela fonctionne, mais j'ai un en-tête de section dans la liste et cet en-tête n'est plus sticky - il se déplace avec la liste :(.



21
votes

Vous pouvez le faire en modifiant l' UITableView de UITableView .

UITableView.appearance().backgroundColor = UIColor.clear

il suffit de mettre cette ligne dans Appdelegate de didFinishLaunchingWithOptions méthode. En remplacement de UIColor.clear définissez la couleur que vous souhaitez ajouter à la couleur d'arrière-plan de la list .


3 commentaires

Cela fonctionne mais cela ne supprime pas le fond blanc sous les lignes qui sont réellement affichées


Il fait le travail: UITableViewCell.appearance (). BackgroundColor = .clear


Existe-t-il une solution pour Mac pour cela?



27
votes

entrez la description de l'image ici

struct ContentView: View {

    var strings = ["a", "b"]

    var body: some View {

        List {
            ForEach(strings, id: \.self) { string in
                Text(string)
            }.listRowBackground(Color.green)
        }
    }
}


3 commentaires

Cela fonctionne mais je suis toujours coincé à trouver comment changer l'arrière-plan de la liste elle-même.


C'est le seul qui fonctionne aussi pour moi. Je pense qu'il est important de souligner que vous devez avoir List { ForEach(elements) { }} par opposition à List(elements) { } pour que ce modificateur fonctionne.


Insensé que la façon dont vous spécifiez les données dans la liste empêche ce modificateur de fonctionner. Ne laisse pas une bonne vue sur SwiftUI dans son ensemble en voyant ce genre de bugs en son sein.



0
votes

J'ai inspiré une partie du configurateur utilisé pour configurer le style de barre de navigation NavigationView par page et écrire un simple configurateur UITableView par page sans utiliser l'approche globale UITableView.appearance ()

List {

}.background(TableViewConfigurator {
    $0.backgroundColor = .red
})

Ensuite, l'extension UIView est nécessaire pour trouver tous les UITableViews

extension UIView {
    func subviews<T:UIView>(ofType WhatType:T.Type) -> [T] {
        var result = self.subviews.compactMap {$0 as? T}
        for sub in self.subviews {
            result.append(contentsOf: sub.subviews(ofType:WhatType))
        }
        return result
    }
}

Et l'utilisation à la fin est:

   import SwiftUI

    struct TableViewConfigurator: UIViewControllerRepresentable {

        var configure: (UITableView) -> Void = { _ in }

        func makeUIViewController(context: UIViewControllerRepresentableContext<TableViewConfigurator>) -> UIViewController {

            UIViewController()
        }

        func updateUIViewController(_ uiViewController: UIViewController, context: UIViewControllerRepresentableContext<TableViewConfigurator>) {

            let tableViews = uiViewController.navigationController?.topViewController?.view.subviews(ofType: UITableView.self) ?? [UITableView]()

            for tableView in tableViews {
                self.configure(tableView)
            }
        }
    }

Peut-être qu'une chose devrait être améliorée qui est l'utilisation de navigationController? .TopViewController pour le faire fonctionner même sans navigationController dans la hiérarchie des contrôleurs de vue


1 commentaires

Cela n'a pas fonctionné pour moi dans Swift 5.2



1
votes

Pour moi, une solution parfaite pour changer l'arrière-plan de List dans SwiftUI est:

struct SomeView: View {
    init(){
    UITableView.appearance().backgroundColor = UIColor(named: "backgroundLight")
      }
...

}


0 commentaires

25
votes

Cela définira l'arrière-plan de toute la liste en vert:

init() {
   UITableView.appearance().separatorStyle = .none
   UITableViewCell.appearance().backgroundColor = .green
   UITableView.appearance().backgroundColor = .green
}


4 commentaires

Comment pourrais-je varier cela entre différentes listes? J'ai appliqué cela à une liste dans un onglet, et cela a affecté l'autre liste dans un autre onglet.


Nice, peut également utiliser: UITableView.appearance (). SeparatorColor = .darkGray


@ glothais-kwl avez-vous trouvé un moyen de "réinitialiser" les apparences de TableView !? Comme vous, j'aimerais cela sur certaines vues et non sur toutes et j'ai besoin d'un moyen de le réinitialiser en fonction de la vue affichée.


Ne fonctionne pas dans SwiftUI 2.0



1
votes

La liste n'est pas encore parfaite.

Une option serait de l'utiliser comme ceci -> List { ForEach(elements) { }} au lieu de List($elements)

De mon côté, c'est ce qui a le mieux fonctionné jusqu'à présent. Comme @FontFamily l'a dit, cela ne devrait briser aucun comportement par défaut de List comme le balayage.


3 commentaires

Cela tue les fonctionnalités de onDelete et onMove pour les éléments de liste imbriqués.


Est-ce que ça le tue pour le deuxième exemple que j'ai donné? Je pense qu'avec la List { ForEach(elements) } ça devrait aller, non?


Vous avez raison - cela fonctionne pour le deuxième exemple que vous avez donné.



2
votes

.colorMultiply (...)

Pour l'arrière-plan de la liste, utilisez le .colorMultiply(Color.yourColor)

Exemple:

List (elements, id:\.self ) { element in

     Text(element)

}
.colorMultiply(Color.red) <--------- replace with your color

entrez la description de l'image ici


1 commentaires

fonctionne bien, mais si l'utilisateur passe en mode sombre, il échoue lamentablement. Je pense que c'est un bogue SwiftUI



3
votes

Il y a un argument: listRowBackground () dans SwiftUI, mais si vous utilisez List directement pour itérer la collection de données, cela ne fonctionne pas.

Voici ma solution de contournement:

    List {
        // To make the background transparent, we have we use a ForEach as a wrapper
        ForEach(files) {file in
            Label(
                title: { Text(file.name ?? fileOptionalFiller).lineLimit(listRowTextLineLimit) },
                icon: { AppIcon.doc.foregroundColor(.primary) }
            )
        }
        .listRowBackground(Color.primary.colorInvert())
    }

Fondamentalement, listRowBackground () fonctionne si vous utilisez un ForEach à l'intérieur de List.


0 commentaires

0
votes

Si quelqu'un est venu ici à la recherche de solutions pour l'arrière-plan en paysage non pleine largeur sur l'iPhone X / 11, essayez:

.listRowBackground(Color("backgroundColour").edgesIgnoringSafeArea(.all))


0 commentaires