May 8, 2024

66. Выбираем подходящую по размеру вьюху

Задача: необходимо выбрать наиболее подходящую вьюху в зависимости от доступного пространства и предпочтений пользователя. Решение: используем ViewThatFits(iOS 16+) для автоматического подбора оптимального варианта.

Сделаем вьюху, которая может выглядеть по-разному в зависимости от ориентации девайса:

  1. При портретной ориентации текст будет сверху, а кнопки снизу
  2. При ландшафтной ориентации весь контент будет умещаться в одну строку
Скриншот для портретной ориентации, контент собирается в VStack
Скриншот для ландшафтной ориентации, контент собирается в HStack

Код для экрана

struct ViewThatFitsExample: View {
  let date: Date
   
  var body: some View {
    ViewThatFits(in: .horizontal) { // <- магия происходит тут
      horizontalView
      compactView
    }
    .padding(.horizontal, 20)
  }
   
  private var horizontalView: some View {
    HStack(spacing: 24) {
      leftButton
      dateView
      rightButton
      resetButton
    }
  }
   
  private var compactView: some View {
    VStack(spacing: 8) {
      dateView
      HStack {
        leftButton
        resetButton
        rightButton
      }
    }
  }
}

Как это работает

Принцип работы ViewThatFits очень простой - он последовательно проверяет каждую из предложенных вьюх, пока не найдет ту, которая полностью помещается в доступном пространстве. При этом проверка идет сверху вниз.

Таким образом, пользователь всегда видит оптимальный вариант, независимо от размера экрана его устройства.

Поменяем порядок вьюх

Поменяем местами horizontalView и compactView:

var body: some View {
  ViewThatFits(in: .horizontal) {
    compactView // <- было вторым, стало первым
    horizontalView // <- было первым, стало вторым
  }
  .padding(.horizontal, 20)
}
Скриншот для ландшафтной ориентации, контент собирается в VStack

Все получилось как и написано в документации - SwiftUI прошелся по всем вьюхам внутри ViewThatFits сверху вниз и нашел первую подходящую вьюху для отображения. Поскольку первая вьюха отображает контент вертикально, то это мы и видим на превью.

Как быть на iOS < 16

На более старых версиях iOS как вариант можно проверять horizontalSizeClass, габариты экрана или вообще модель девайса (способ дикий, чаще проверяется наличие "челки"), в зависимости от ваших предпочтений и выбора команды.

Заключение

Использование ViewThatFits особенно полезно при создании адаптивных интерфейсов, которые должны одинаково хорошо выглядеть на устройствах с разными размерами экранов - это позволяет нам сосредоточиться на создании контента, а не на ручной подгонке макета под каждый девайс.

Код для этой статьи можно посмотреть тут, а другие статьи - тут.