Section в SwiftUI: что это, создание секций и группировка

Автор: IT Sectr Опубликовано: 2026-06-25 Время чтения: 7 мин

Section в SwiftUI — контейнерный компонент для логической группировки элементов внутри Form или List. Компонент отображает содержимое как визуальный блок с системными отступами, закруглёнными углами и опциональными заголовком и футером. По данным Apple Developer Documentation (2025), Section не управляет данными, а только организует представление: все дочерние элементы наследуют её стиль и отступы, обеспечивая структурированное отображение форм и списков.

Главное

  • Section — контейнер для логической группировки элементов в Form и List
  • Заголовок Section отображается над группой элементов системным шрифтом
  • Футер добавляет поясняющий текст под группой меньшим шрифтом
  • ForEach внутри Section позволяет создавать динамические группы
  • Вложенные секции поддерживаются для иерархической организации контента

Что такое Section в SwiftUI?

Section — это структурный компонент SwiftUI, предназначенный для группировки элементов внутри контейнеров Form и List. В отличие от VStack или HStack, Section добавляет системные отступы, заголовок и футер, а также визуальное выделение группы в виде блока с закруглёнными углами на iOS.

Section не изменяет поведение дочерних элементов — она только организует их представление. Все контролы внутри Section — Picker, Toggle, TextField — работают как обычно, но визуально объединены в логическую группу. Это особенно важно для экранных форм, где пользователь должен быстро ориентироваться в структуре вводимых данных.

Система автоматически управляет отступами между секциями: расстояние между Section на iOS составляет 16–20 пунктов, между элементами внутри Section — 0 (разделитель между строками). Разработчик не может изменить эти отступы через модификаторы padding — они контролируются системой для обеспечения единообразного внешнего вида.

Section принимает два опциональных параметра: header — заголовок группы, и footer — поясняющий текст под группой. Заголовок отображается над элементами секции полужирным шрифтом caption-стиля, футер — меньшим шрифтом с серым цветом. Оба параметра принимают любую SwiftUI View, не только Text.

Заголовок Section помогает пользователю понять, к какой категории относятся элементы внутри группы. Например, на экране настроек заголовки «Уведомления», «Приватность» и «Аккаунт» мгновенно ориентируют пользователя. Футер уместен для пояснений: «Отключите уведомления на время встречи» или «Пароль должен содержать не менее 8 символов». Футер автоматически переносится на несколько строк при необходимости.

swift
Section(
    header: Text("Account Security"),
    footer: Text("Use a strong password with at least 8 characters.")
) {
    SecureField("Current password", text: $currentPassword)
    SecureField("New password", text: $newPassword)
}

В примере Section имеет заголовок «Account Security» и футер с советом по безопасности пароля. Пользователь видит заголовок как метку раздела, заполняет два поля и сразу читает предупреждение под ними. Такая структура улучшает UX, так как вся информация о разделе находится на одном экране без необходимости переходить к отдельной справке.

Section внутри Form и List

Section работает как внутри Form, так и внутри List, но визуальное представление различается. В Form Section отображается как блок с закруглёнными углами и системным фоном, отделённый от соседних секций отступами. В List Section может использовать стиль plain — без фона и закруглений, или inset-grouped — с закруглёнными блоками, аналогично Form.

Выбор контейнера влияет на стиль Section. Если разместить Section с одинаковым содержимым внутри Form и List со стилем .insetGrouped, результат будет идентичным. Однако Form добавляет системные отступы и по умолчанию использует grouped-стиль, тогда как List требует явного указания стиля через модификатор .listStyle(.insetGrouped).

КонтейнерSection по умолчаниюДоступные стили
FormInsetGrouped с закруглёнными углами.grouped (только Form)
ListPlain — без фона секции.plain, .inset, .insetGrouped, .sidebar

Для достижения одинакового внешнего вида в List используйте .listStyle(.insetGrouped). Этот стиль имитирует внешний вид Form и подходит для экранов настроек, построенных на List. Для стандартных списков данных используйте .plain — без выделения секций, с тонкими разделителями между строками.

Динамический контент через ForEach

Section может содержать динамическое количество элементов через ForEach. Это позволяет создавать группы с повторяющимися элементами, сохраняя заголовок и футер для всей группы. ForEach внутри Section итерирует коллекцию данных и создаёт дочерние View для каждого элемента, не нарушая структуру секции.

Динамические секции полезны для экранов настроек с переменным количеством опций: список языков, доступных для выбора, перечень подключённых устройств или список push-подписок. Заголовок секции остаётся статическим, а содержимое меняется в зависимости от данных.

swift
struct DynamicSectionView: View {
    let categories = ["Work", "Personal", "Finance", "Health"]
    @State private var selected = Set<String>()

    var body: some View {
        Form {
            Section(header: Text("Categories"),
                    footer: Text("Select your preferred categories")) {
                ForEach(categories, id: \.self) { category in
                    Toggle(category, isOn: Binding(
                        get: { selected.contains(category) },
                        set: { if $0 { selected.insert(category) }
                                     else { selected.remove(category) } }
                    ))
                }
            }

            Section {
                Text("Selected: \(selected.count) categories")
                    .foregroundStyle(.secondary)
            }
        }
    }
}

В этом примере ForEach генерирует Toggle для каждой категории из массива categories. Заголовок и футер секции заданы один раз и применяются ко всей группе. Вторая секция отображает количество выбранных категорий — она не зависит от ForEach и остаётся статической. Такой подход позволяет создавать гибкие формы, где заголовок и футер контекстуализируют группу динамических элементов.

Примеры кода Section

Рассмотрим полноценный пример экрана профиля с использованием Section для группировки данных. Форма содержит три секции: информация о пользователе, настройки приватности и статистика. Каждая секция использует свой заголовок, а последняя — футер с итоговой информацией.

swift
struct ProfileView: View {
    @State private var displayName = "Alex Johnson"
    @State private var bio = "iOS developer"
    @State private var isProfilePublic = true
    @State private var showEmail = false

    var body: some View {
        Form {
            Section(header: Text("Profile Info")) {
                TextField("Display name", text: $displayName)
                TextField("Bio", text: $bio, axis: .vertical)
                    .lineLimit(3)
            }

            Section(header: Text("Privacy")) {
                Toggle("Public profile", isOn: $isProfilePublic)
                Toggle("Show email", isOn: $showEmail)
                    .disabled(!isProfilePublic)
            }

            Section(header: Text("Stats"),
                    footer: Text("Last updated today at 2:30 PM")) {
                LabeledContent("Posts", value: "42")
                LabeledContent("Followers", value: "1,280")
                LabeledContent("Following", value: "346")
            }
        }
        .navigationTitle("Profile")
    }
}

Три Section чётко разделяют функциональные блоки: редактируемые поля профиля, переключатели приватности и статистику. Вторая секция демонстрирует валидацию: Toggle «Show email» отключён, пока профиль не публичный. Футер третьей секции показывает время последнего обновления — пример использования футера для дополнительной контекстной информации. LabeledContent — стандартный компонент SwiftUI для отображения пары «ключ-значение» в Form.

Section с кастомным заголовком

swift
Section(
    header: HStack {
        Image(systemName: "bell.fill")
            .foregroundStyle(.blue)
        Text("Notifications")
            .font(.headline)
    },
    footer: Text("Manage push and email alerts")
) {
    Toggle("Push notifications", isOn: $push)
    Toggle("Email notifications", isOn: $email)
    Stepper("Quiet hours: \(quietStart) — \(quietEnd)",
            value: $quietStart,
            in: 0...23)
}

Этот пример показывает, что header может быть любой SwiftUI View. Использование HStack с Image и Text позволяет добавить иконку рядом с заголовком, делая секцию визуально более выразительной. Кастомные заголовки полезны для выделения важных разделов в интерфейсе: настройки уведомлений, платные функции или разделы с предупреждениями. Однако злоупотреблять кастомными заголовками не стоит — на каждом экране достаточно 1–2 секций с нестандартным оформлением, чтобы сохранить единообразие интерфейса.

Часто задаваемые вопросы

Можно ли вкладывать Section друг в друга?

Нет, Section не поддерживает вложенность в SwiftUI. Попытка поместить Section внутрь другой Section приводит к ошибке компиляции. Для иерархической группировки используйте List с OutlineGroup или DisclosureGroup внутри Section.

Как изменить отступы между Section?

Отступы между Section управляются системой и не могут быть изменены через модификаторы padding. На iOS расстояние между секциями составляет 16–20 пунктов и соответствует HIG. Единственный способ повлиять на отступы — использовать кастомный ListStyle, но это не рекомендуется.

Чем Section отличается от Group в SwiftUI?

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

Поддерживает ли Section Accessibility?

Да, Section автоматически добавляет accessibility-метки. Заголовок секции становится accessibility-заголовком группы, футер — accessibility-подсказкой. VoiceOver читает заголовок перед входом в секцию, что улучшает навигацию для пользователей с ограниченными возможностями.

Можно ли использовать Section без Form или List?

Нет, Section работает только внутри Form или List. Использование Section вне этих контейнеров приводит к ошибке компиляции. Для группировки элементов в VStack или ScrollView используйте Group или кастомные View с настройкой отступов вручную.

Итоги

  • Section — контейнер группировки элементов в Form и List с системными отступами
  • Header и footer — опциональные параметры для контекстной информации о группе
  • ForEach внутри Section позволяет создавать динамические группы с повторяющимися элементами
  • Вложенность Section запрещена — для подгрупп используйте DisclosureGroup
  • Стиль Section зависит от контейнера: Form использует insetGrouped, List — plain по умолчанию
  • Кастомный header может быть любой SwiftUI View с иконкой и кастомным шрифтом
  • Используйте Section для логической группировки полей ввода и настроек

Мы разработаем мобильное приложение под ключ

IT Sectr создаёт приложения для iOS и Android для стартапов и бизнеса с 2017 года. Мы проконсультируем вас и предложим наилучшее решение.

Обсудить проект

Читайте также