Адаптация приложения к разным размерам экрана необходима для обеспечения отличного пользовательского опыта на всех устройствах. SwiftUI предоставляет различные шаблоны, инструменты и техники для достижения этой цели. В этом посте приведены некоторые примеры, которые помогут вам адаптировать пользовательский интерфейс.
1. Использование @Environment
для получения характеристик устройства
Обертку свойства @Environment
в SwiftUI можно использовать для получения информации о текущем окружении, например, классов горизонтального и вертикального размера.
import SwiftUI struct ContentView: View { enum Constants { static let threeColumnLayout = [GridItem(.flexible(), spacing: 16), GridItem(.flexible(), spacing: 16), GridItem(.flexible(), spacing: 0)] static let oneColumnLayout = [GridItem(.flexible(), spacing: 0)] } @Environment(\.horizontalSizeClass) var horizontalSizeClass: UserInterfaceSizeClass? @State var gridLayout = Constants.oneColumnLayout let items = Array(0...50).map { "\($0)"} var body: some View { ScrollView { LazyVGrid(columns: gridLayout) { ForEach(items, id: \.self) { item in Text("Cell title № \(item)") .padding(16) .frame(maxWidth: .infinity) .background(.mint) } } } .onChange(of: horizontalSizeClass) { _, newValue in setGridLayout(for: newValue) } .onAppear { setGridLayout(for: horizontalSizeClass) } } private func setGridLayout(for sizeClass: UserInterfaceSizeClass?) { gridLayout = sizeClass == .regular ? Constants.threeColumnLayout : Constants.oneColumnLayout } }
В этом примере показано, как можно отобразить 1 или 3 колонки в зависимости от ширины экрана.
2. Использование GeometryReader
и условных представлений/модификаторов
GeometryReader
— это мощное представление, которое дает вам доступ к размеру и положению родительского представления. Вы можете использовать его с условными операторами для адаптации пользовательского интерфейса в зависимости от доступного пространства.
import SwiftUI struct ItemView: View { let textToDisplay: String var body: some View { HStack { GeometryReader { geometry in HStack { Text("Cell title № \(textToDisplay)") Spacer() Button("Button 1") { } .padding(8) .background(.white) if geometry.size.width > 400 { Button("Button 2") { } .padding(8) .background(.white) } } .padding(16) } } .frame(maxWidth: .infinity) .background(.mint) } }
3. Адаптивный сетчатый макет
Аналогично первому примеру. Этот подход предпочитает вставлять как можно больше элементов `минимального` размера. Лично я предпочитаю первый подход, потому что мы обычно хотим контролировать количество колонок, но, конечно, это зависит от ваших требований.
import SwiftUI struct ContentView: View { let items = Array(0...50).map { "\($0)"} var body: some View { ScrollView { LazyVGrid(columns: [GridItem(.adaptive(minimum: 60))]) { ForEach(items, id: \.self) { item in Text("\(item)") .padding(16) .frame(maxWidth: .infinity) .background(.purple) } } } } }
Конечно, существуют и другие модификаторы — LayoutPriority
, Spacer
, AspectRatio
, которые служат той же цели. Используя все эти приемы, вы сможете создать гибкий и адаптивный пользовательский интерфейс, который будет отлично смотреться на всех устройствах, от маленьких iPhone до больших iPad и не только.