web-dev-qa-db-fra.com

UICollectionView et SwiftUI?

Comment créer une grille d'éléments carrés (par exemple comme dans la photothèque iOS) avec SwiftUI?

J'ai essayé cette approche mais cela ne fonctionne pas:

var body: some View {
    List(cellModels) { _ in
        Color.orange.frame(width: 100, height: 100)
    }
}

La liste a toujours le style UITableView:

enter image description here

28
Evgeny Mikhaylov

Fatigué de trouver de nombreuses solutions compliquées ou des bibliothèques Github, j'ai décidé de faire ma propre solution, simple et belle mathématique.

  1. Pensez que vous disposez d'un éventail d'articles var items : [ITEM] = [...YOUR_ITEMS...]
  2. Vous souhaitez afficher une grille de Nx2

Lorsque N est le nombre de [~ # ~] lignes [~ # ~] et 2 est le nombre de [~ # ~] colonnes [~ # ~]

  1. Pour afficher tous les éléments, vous devez utiliser deux instructions ForEach, une pour les colonnes et une pour les lignes.

Dans les deux ForEach: (i) index actuel des [~ # ~] lignes [~ # ~] , et (j) index actuel des colonnes [~ # ~] [~ # ~]

  1. Afficher l'élément actuel dans l'index [(i * 2) + j]
  2. Passons maintenant au code:

Remarque: Xcode 11.3.1

var items : [ITEM] = [...YOUR_ITEMS...]
var body: some View {
VStack{
    // items.count/2 represent the number of rows
    ForEach(0..< items.count/2){ i in
        HStack(alignment: .center,spacing: 20){
            //2 columns 
            ForEach(0..<2){ j in
               //Show your custom view here
               // [(i*2) + j] represent the index of the current item 
                ProductThumbnailView(product: self.items[(i*2) + j])
            }
        }
        }.padding(.horizontal)
    Spacer()
   }
}
0
iGhost

Sur la base de la réponse de Will, j'ai tout enveloppé dans un SwiftUI ScrollView. Vous pouvez donc réaliser un défilement horizontal (dans ce cas) ou vertical.

Il utilise également GeometryReader, il est donc possible de calculer avec la taille d'écran.

GeometryReader{ geometry in
 .....
 Rectangle()
    .fill(Color.blue)
    .frame(width: geometry.size.width/6, height: geometry.size.width/6, alignment: .center)
 }

Voici un exemple de travail:

import SwiftUI

struct MaterialView: View {

  var body: some View {

    GeometryReader{ geometry in

      ScrollView(Axis.Set.horizontal, showsIndicators: true) {
        ForEach(0..<2) { _ in
          HStack {
            ForEach(0..<30) { index in
              ZStack{
                Rectangle()
                  .fill(Color.blue)
                  .frame(width: geometry.size.width/6, height: geometry.size.width/6, alignment: .center)

                Text("\(index)")
              }
            }
          }.background(Color.red)
        }
      }.background(Color.black)
    }

  }
}

struct MaterialView_Previews: PreviewProvider {
  static var previews: some View {
    MaterialView()
  }
}

enter image description here

0
Peter Pohlmann

Essayez d'utiliser un VStack et HStack

var body: some View {
    GeometryReader { geometry in
        VStack {
            ForEach(1...3) {_ in
                HStack {
                    Color.orange.frame(width: 100, height: 100)
                    Color.orange.frame(width: 100, height: 100)
                    Color.orange.frame(width: 100, height: 100)
                }.frame(width: geometry.size.width, height: 100)
            }
        }
    }
}

Vous pouvez encapsuler dans un ScrollView si vous voulez faire défiler

0
Krames