UICollectionView и SwiftUI? - PullRequest
       39

UICollectionView и SwiftUI?

20 голосов
/ 05 июня 2019

Как создать сетку из квадратных элементов (например, как в iOS Photo Library) с SwiftUI?

Я пробовал этот подход, но он не работает:

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

Список по-прежнему имеет стиль UITableView:

enter image description here

Ответы [ 6 ]

7 голосов
/ 07 июня 2019

Одним из возможных решений является упаковка UICollectionView в UIViewRepresentable.См. Объединение и создание представлений Учебное пособие по SwiftUI, где они обертывают MKMapView в качестве примера.

В настоящее время в SwiftUI нет эквивалента UICollectionView и нет планадля этого еще.См. Обсуждение под этим твит .

Чтобы получить более подробную информацию, посмотрите Интеграция SwiftUI WWDC видео (~ 8: 08).

0 голосов
/ 19 июля 2019

QGrid - небольшая библиотека, которую я создал, которая использует тот же подход, что и представление List SwiftUI, вычисляя его ячейки по требованию из базовой коллекции идентифицированных данных:

В простейшем виде QGrid может использоваться только с этой 1 строкой кода в теле вашего View, при условии, что у вас уже есть пользовательский вид ячейки:

struct PeopleView: View {
  var body: some View {
    QGrid(Storage.people, columns: 3) { GridCell(person: $0) }
  }
}   

struct GridCell: View {
  var person: Person
  var body: some View {
    VStack() {
      Image(person.imageName).resizable().scaledToFit()
      Text(person.firstName).font(.headline).color(.white)
      Text(person.lastName).font(.headline).color(.white)
    }
  }
}

enter image description here


Вы также можете настроить конфигурацию макета по умолчанию:

struct PeopleView: View {
  var body: some View {
    QGrid(Storage.people,
          columns: 3,
          columnsInLandscape: 4,
          vSpacing: 50,
          hSpacing: 20,
          vPadding: 100,
          hPadding: 20) { person in
            GridCell(person: person)
    }
  }
} 

Пожалуйста, ознакомьтесь с демонстрационным GIF и тестовым приложением в репозитории GitHub:

https://github.com/Q-Mobile/QGrid

0 голосов
/ 09 июля 2019

Я написал небольшой компонент с именем ridGridStack, который создает сетку, которая подстраивается под доступную ширину.Даже когда это меняется динамически, как при повороте iPad.

https://github.com/pietropizzi/GridStack

Основы этой реализации аналогичны тем, что другие ответили здесь (поэтому HStack s внутри VStack) с той разницей, что она вычисляет ширину в зависимости от доступной ширины и конфигурации, которую вы передаете ей.

  • С помощью minCellWidth вы определяете наименьшую ширину, которую должен иметь ваш элемент в сетке.
  • С помощью spacing вы определяете пространство между элементами в сетке.

например,

GridStack(
    minCellWidth: 320,
    spacing: 15,
    numItems: yourItems.count
) { index, cellWidth in
    YourItemView(item: yourItems[index]).frame(width: cellWidth)
}
0 голосов
/ 18 июня 2019

Думая в SwiftUI, есть простой способ:

struct MyGridView : View {
var body: some View {
    List() {
        ForEach(0..<8) { _ in
            HStack {
                ForEach(0..<3) { _ in
                    Image("orange_color")
                        .resizable()
                        .scaledToFit()
                }
            }
        }
    }
}

}

Достаточно SwiftUI, если вы хотите, вам иногда нужно забыть, например, UIColectionView ..

enter image description here

0 голосов
/ 09 июня 2019

Я думаю, вы можете использовать прокрутку вот так

struct MovieItemView : View {
    var body: some View {
        VStack {
            Image("sky")
                .resizable()
                .frame(width: 150, height: 200)
            VStack {
                Text("Movie Title")
                    .font(.headline)
                    .fontWeight(.bold)
                Text("Category")
                    .font(.subheadline)
            }
        }
    }
}

struct MoviesView : View {
    var body: some View {
        VStack(alignment: .leading, spacing: 10){
            Text("Now Playing")
                .font(.title)
                .padding(.leading)
            ScrollView {
                HStack(spacing: 10) {
                    MovieItemView()
                    MovieItemView()
                    MovieItemView()
                    MovieItemView()
                    MovieItemView()
                    MovieItemView()
                }
            }
            .padding(.leading, 20)
        }
    }
}
0 голосов
/ 05 июня 2019

Попробуйте использовать VStack и 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)
            }
        }
    }
}

Вы можете обернуть в ScrollView, если хотите прокрутить

...