Как адаптировать интерфейс под iPad в SwiftUI
Что проверяют
Умеете ли вы строить интерфейс от доступного места, а не от модели устройства. Следом обычно спрашивают про многозадачность: как экран поведёт себя в Split View, Slide Over или в окне, которое пользователь сузил вручную.
Как отвечать
- size classes:
@Environment(\.horizontalSizeClass)вместо проверкиUIDevice.current.userInterfaceIdiom. iPad на весь экран даёт.regular, но в узком окне Split View приложение получит.compact, как на iPhone; - навигация:
NavigationSplitViewдаёт боковую панель и детальную область на iPad и сам сворачивается в стек на iPhone и в узком окне.NavigationViewпомечен устаревшим; - ViewThatFits: перебирает варианты разметки и берёт первый, который помещается, например горизонтальную панель кнопок, а при нехватке места вертикальную;
- AnyLayout: переключает
HStackLayoutиVStackLayoutбез потери состояния дочерних вью, в отличие отifс двумя разными стеками; - сетки:
LazyVGridсGridItem(.adaptive(minimum: 160))сама подбирает число колонок под ширину; - ширина контента: текст во всю ширину 13-дюймового экрана читать тяжело, поэтому колонку ограничивают через
.frame(maxWidth: 700); - особенности iPad:
.hoverEffect()для указателя,.keyboardShortcutдля клавиатуры, контекстные меню,.popover, который на iPad показывается поповером, а на iPhone листом, несколько окон черезWindowGroup.
GeometryReader оставьте для мест, где нужен точный размер: он забирает всё предложенное место, и если обернуть им экран целиком, раскладка начинает вести себя странно.
Проверять стоит не только разные модели iPad, но и обе ориентации, Split View и крупный Dynamic Type.
Где спотыкаются
Проверяют userInterfaceIdiom == .pad и рисуют отдельную «планшетную» версию. В Split View приложение получает узкое окно, и планшетная разметка в нём разваливается.
Строят брейкпоинты на GeometryReader с магическими числами вроде 600 точек, хотя size class и ViewThatFits решают задачу без ручных порогов.
Просто растягивают экран iPhone: списки и кнопки на всю ширину, никакой боковой панели. Пользователь видит увеличенный телефон с огромными пустыми полями.