Site icon AppTractor

SwiftUI: адаптация UI к различным размерам экрана (с примерами кода)

Адаптация приложения к разным размерам экрана необходима для обеспечения отличного пользовательского опыта на всех устройствах. 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 и не только.

Источник

Exit mobile version