Form в SwiftUI — контейнерный компонент для построения структурированных интерфейсов настроек и ввода данных, следующий дизайну Settings в iOS. Компонент автоматически группирует элементы управления в секции с системными отступами и стилями, избавляя разработчика от ручной калибровки разделителей и цветов. По данным Apple Developer Documentation (2025), Form адаптирует внешний вид под каждую платформу — от grouped-таблиц на iOS до стандартных списков на macOS — сохраняя единый API.
Главное
Form — это специализированный контейнер SwiftUI, предназначенный для создания форм ввода и экранов настроек. Он наследует поведение List, но добавляет платформенные стили: на iOS Form отображается как grouped-таблица с закруглёнными углами секций, на macOS — как стандартный системный список с чекбоксами и контролами.
В отличие от ручной вёрстки с VStack и HStack, Form автоматически расставляет отступы между элементами, добавляет разделители и адаптирует внешний вид под системную тему — светлую или тёмную. Разработчик описывает только логическую структуру: Section для группировки и элементы управления внутри. Форма сама решает, как визуально расположить Picker, Toggle или Stepper на конкретной платформе.
Form поддерживает все стандартные SwiftUI-элементы ввода: TextField для текста, SecureField для паролей, Picker для выбора из списка, Toggle для вкл/выкл, Slider для диапазонов, Stepper для пошаговых значений и DatePicker для даты. Каждый элемент автоматически получает стиль, соответствующий HIG (Human Interface Guidelines) Apple на целевой платформе.
Несмотря на внешнее сходство, Form и List решают разные задачи. List — универсальный контейнер для отображения прокручиваемых списков данных с возможностью свайп-действий и редактирования строк. Form — специализированный контейнер для ввода данных и настроек, оптимизированный под системные стили контролов.
List уместен для отображения динамических данных: ленты новостей, чатов, каталогов товаров. Form — для статических экранов с предсказуемым набором полей: профиль пользователя, настройки приложения, регистрационная анкета. Ключевое отличие: элементы Form могут быть интерактивными контролами, тогда как строки List чаще всего отображают данные и реагируют на тап навигацией или действием.
| Параметр | Form | List |
|---|---|---|
| Назначение | Ввод данных, настройки | Отображение списков |
| Стиль секций | Grouped (iOS), системный (macOS) | Plain или Grouped |
| Контролы | Picker, Toggle, Slider, Stepper | Ограниченные (button) |
| Динамические данные | Ограниченно (ForEach внутри Section) | Полная поддержка |
| Свайп-действия | Да, swipeActions | Да, swipeActions |
По данным Apple Human Interface Guidelines (2025), Form следует использовать для экранов настроек и ввода, где на одном экране находится от 3 до 20 элементов управления и разделение на секции улучшает восприятие.
Section — основной строительный блок Form, позволяющий группировать логически связанные элементы. Каждая Section может иметь заголовок, футер и произвольное количество контролов внутри. Система автоматически добавляет отступы между секциями и оборачивает каждую в визуальный блок с закруглёнными углами.
Использование Section критически важно для читаемости формы: элементы, сгруппированные по смыслу, легче воспринимаются пользователем. Например, на экране настроек профиля можно вынести в отдельные секции «Личные данные», «Уведомления» и «Безопасность». Каждая секция может содержать футер с поясняющим текстом, который система отображает меньшим шрифтом под группой элементов.
Form {
Section(header: Text("Profile")) {
TextField("Name", text: $name)
TextField("Email", text: $email)
}
Section(header: Text("Notifications"),
footer: Text("Disable during meetings")) {
Toggle("Push notifications", isOn: $pushEnabled)
Toggle("Email notifications", isOn: $emailEnabled)
}
}
В примере первая секция «Profile» содержит два текстовых поля без футера, вторая секция «Notifications» — два переключателя с пояснением под группой. Футер автоматически добавляет отступ и использует caption-стиль шрифта. Section может содержать футер без заголовка или заголовок без футера.
Form поддерживает все стандартные элементы ввода SwiftUI. Picker в Form автоматически отображается как навигационная строка с переходом на отдельный экран выбора на iOS. Toggle отображается как строка с переключателем, выровненным по правому краю. TextField получает системный стиль ввода с плейсхолдером.
Для числовых значений используются Stepper (пошаговое изменение) и Slider (плавное изменение в диапазоне). DatePicker поддерживает несколько режимов: date, time, dateAndTime. Для выбора цвета доступен ColorPicker. Каждый элемент адаптируется под платформу без дополнительного кода — на iOS контролы используют нативные стили UIKit, на macOS — AppKit.
| Элемент | Назначение | Стиль в Form |
|---|---|---|
| TextField | Ввод текста | Строка с плейсхолдером |
| SecureField | Ввод пароля | Строка со скрытыми символами |
| Picker | Выбор из списка | NavigationLink к экрану выбора |
| Toggle | Вкл/Выкл | Строка с переключателем |
| Slider | Диапазон значений | Горизонтальный слайдер |
| DatePicker | Выбор даты/времени | Компактный или колёсный стиль |
Для кастомных контролов внутри Form можно использовать любые SwiftUI View — они наследуют стандартное поведение секции. Однако рекомендуется придерживаться системных элементов, так как они гарантируют соответствие HIG и поддерживают Accessibility (VoiceOver, Dynamic Type) без дополнительной настройки.
Рассмотрим создание экрана регистрации с использованием Form. Форма содержит четыре секции: личные данные, выбор роли, настройки подписки и кнопку отправки. Используются Section для группировки и стандартные контролы SwiftUI.
struct RegistrationForm: View {
@State private var name = ""
@State private var email = ""
@State private var role = "Developer"
@State private var agreedToTerms = false
let roles = ["Developer", "Designer", "Manager"]
var body: some View {
NavigationStack {
Form {
Section(header: Text("Personal Info")) {
TextField("Name", text: $name)
TextField("Email", text: $email)
.keyboardType(.emailAddress)
}
Section(header: Text("Role")) {
Picker("Select role", selection: $role) {
ForEach(roles, id: \.self) { role in
Text(role).tag(role)
}
}
}
Section {
Toggle("Agree to terms", isOn: $agreedToTerms)
}
Section {
Button("Register") {
submitForm()
}
.disabled(!agreedToTerms)
}
}
.navigationTitle("Registration")
}
}
private func submitForm() { }
}
Форма разбита на четыре Section: личные данные с двумя текстовыми полями, выбор роли через Picker, согласие с условиями через Toggle и кнопка регистрации. Кнопка отключена, пока пользователь не согласится с условиями — это пример валидации внутри Form. NavigationStack добавляет заголовок и позволяет Picker открывать отдельный экран выбора на iOS.
struct SettingsForm: View {
@State private var volume: Double = 0.5
@State private var isDarkMode = false
@State private var reminderDate = Date()
var body: some View {
NavigationStack {
Form {
Section(header: Text("Appearance")) {
Toggle("Dark mode", isOn: $isDarkMode)
Slider(value: $volume, in: 0...1) {
Text("Volume")
}
}
Section(header: Text("Reminders"),
footer: Text("You\'ll get a notification at the selected time")) {
DatePicker("Remind at",
selection: $reminderDate,
displayedComponents: .hourAndMinute)
}
Section {
NavigationLink("Advanced Settings",
destination: AdvancedSettingsView())
}
}
.navigationTitle("Settings")
}
}
}
Этот пример демонстрирует комбинацию Slider, DatePicker и NavigationLink внутри Form. DatePicker использует режим hourAndMinute для отображения только времени. NavigationLink в последней секции создаёт переход на экран расширенных настроек — распространённый паттерн для Settings-like интерфейсов. Заголовки и футеры секций делают форму самодокументируемой: пользователь сразу понимает, к какой группе относится каждый элемент управления.
Часто задаваемые вопросы
Form оптимизирован для ввода данных и настроек: элементы управления получают системные стили, секции — закруглённые углы и отступы. List — универсальный контейнер для отображения данных. Form подходит для экранов настроек, List — для чатов, лент, каталогов.
Да, Picker внутри Form автоматически отображается как строка с выбранным значением и NavigationLink для выбора из списка на iOS. На macOS Picker отображается как выпадающий список или radio group в зависимости от стиля. Адаптация происходит без дополнительного кода.
Любая SwiftUI View может быть помещена внутрь Form или Section. Для кастомных контролов рекомендуется наследовать стандартные отступы секции и поддерживать Dynamic Type через системные шрифты. Избегайте фиксированных размеров и цветов, чтобы форма корректно отображалась на всех устройствах.
Да, Form автоматически оборачивается в ScrollView, если контент превышает высоту экрана. Не нужно добавлять ScrollView вручную — система сама определяет необходимость прокрутки. Для форм, которые не должны прокручиваться, используйте VStack с фиксированной высотой.
Form на iOS поддерживает два стиля через модификатор .formStyle(.grouped) — стандартный grouped-вид с закруглёнными секциями. Для macOS доступен .formStyle(.columns) с многоколоночным расположением. Стиль применяется ко всей Form сразу и меняет визуальное представление всех элементов внутри.
Итоги
Мы разработаем мобильное приложение под ключ
IT Sectr создаёт приложения для iOS и Android для стартапов и бизнеса с 2017 года. Мы проконсультируем вас и предложим наилучшее решение.
Читайте также