Начиная с iOS 14 в SwiftUI добавили два новых представления LazyVGrid
и LazyHGrid
для отображения представлений в виде сетки с несколькими колонками/столбцами. Слово Lazy означает, что представление сетки не создает элементы, пока они не понадобятся.
Первым шагом к использованию сетки есть создание списка элементов.
var colors: [Color] = [.orange, .green, .gray]
Затем создайте массив GridItem
, описывающий как выглядит сетка. Вот пример фрагмента кода для описания сетки из двух столбцов
var grid = [GridItem(.flexible()), GridItem(.flexible())]
Наконец, разместите сетку, используя LazyVGrid
и ScrollView
.
ScrollView { LazyVGrid(columns: threeColumnGrid) { // Display the item } }
Вы используете экземпляр GridItem
для настройки расположения элементов в представлениях LazyHGrid
и LazyVGrid
. Элемент сетки представляет собой строку или столбец.
GridItems
объявляются с использованием следующего синтаксиса
GridItem(sizing, spacing, alignment)
Есть три варианта указания размера элемента сетки.
flexible(minimum: CGFloat, maximum: CGFloat)
указывает один гибкий элемент в доступном пространстве с необязательными параметрами для минимального и максимального размера.adaptive(minimum: CGFloat, maximum: CGFloat)
указывает, что размер строки или столбца регулируется таким образом, чтобы максимально возможное количество элементов помещалось в доступное пространство.fixed(CGFloat)
определяет один элемент фиксированного размера в доступном пространстве.Flexible
Flexible макет сетки позволяет указать диапазон размеров, определяя при этом количество столбцов. Мы можем предоставить минимум и максимум, но и без этого он прекрасно работает. Размер элемента рассчитывается путем деления доступного пространства на количество элементов.
struct ContentView: View { private var colors: [Color] = [.orange, .green, .gray] private var items = [GridItem(.flexible(minimum: 60)), GridItem(.flexible()), GridItem(.flexible())] struct ItemView: View { var index: Int var color: Color var body: some View { Text("\(index)") .frame(minWidth: 50, maxWidth: .infinity, minHeight: 100) .background(color) .cornerRadius(4) } } var body: some View { ScrollView { LazyVGrid(columns: items, spacing: 4) { ForEach((0...10), id: \.self) { index in ItemView(index: index, color: colors[index % colors.count]) } } .padding(4) } } }
Adaptive
Adaptive макет сетки является, наверное, наиболее используемым. Он заполняет пространство таким количеством столбцов или строк, которое помещается в сетку. Чтобы использовать адаптивный размер, измените массив items
, чтобы он содержал один адаптивный элемент, как показано ниже
private var items = [GridItem(.adaptive(minimum: 80))]
Это изменение приведет к тому, что в сетке будет отображаться как можно больше столбцов с ограничением, согласно которому ширина столбца не может быть меньше 80 dp.
Fixed
Fixed макета сетки позволяет задавать строки или столбцы определенного размера. При использовании только фиксированных GridItems
в списке, количество элементов будет определять количество строк или столбцов. Например, следующий список при передаче в представление LazyVGrid
отобразит сетку, содержащую один столбец шириной 80 dp.
private var items = [GridItem(.fixed(80))]
С другой стороны, следующий список будет отображать сетку из трех столбцов со столбцами размером 30dp, 40dp и 50dp соответственно.
private var items = [GridItem(.fixed(30)), GridItem(.fixed(40)), GridItem(.fixed(50))]
При работе с сетками также можно комбинировать конфигурации размеров GridItem
. Например, следующий список будет отображать первый столбец каждой строки с фиксированной шириной, а второй и третий столбцы будут иметь одинаковый размер, чтобы занимать оставшееся место
private var items = [GridItem(.fixed(30)), GridItem(), GridItem()]
LazyHGrid
Горизонтальные сетки работают почти так же, как вертикальные, за исключением того, что конфигурация основана на строках, а не на столбцах, и значения minimum и maximum относятся к высоте строки, а не к ширине столбца.
struct ContentView: View { private var colors: [Color] = [.orange, .green, .gray] private var items = [GridItem(.adaptive(minimum: 40))] struct ItemView: View { var index: Int var color: Color var body: some View { Text("\(index)") .frame(minWidth: 50, minHeight: 50, maxHeight: .infinity) .background(color) .cornerRadius(4) } } var body: some View { ScrollView(.horizontal) { LazyHGrid(rows: items, spacing: 4) { ForEach((0...50), id: \.self) { index in ItemView(index: index, color: colors[index % colors.count]) } } .padding(4) } } }