Section w SwiftUI to komponent kontenerowy do logicznego grupowania elementów wewnątrz Form lub List. Komponent wyświetla zawartość jako blok wizualny z systemowymi odstępami, zaokrąglonymi rogami i opcjonalnym nagłówkiem oraz stopką. Według Apple Developer Documentation (2025), Section nie zarządza danymi, a jedynie organizuje prezentację: wszystkie elementy podrzędne dziedziczą jej styl i odstępy, zapewniając strukturalne wyświetlanie formularzy i list.
Najważniejsze
Section to strukturalny komponent SwiftUI przeznaczony do grupowania elementów wewnątrz kontenerów Form i List. W przeciwieństwie do VStack lub HStack, Section dodaje systemowe odstępy, nagłówek i stopkę, a także wizualne wyróżnienie grupy w postaci bloku z zaokrąglonymi rogami w iOS.
Section nie zmienia zachowania elementów podrzędnych — jedynie organizuje ich prezentację. Wszystkie kontrolki wewnątrz Section — Picker, Toggle, TextField — działają normalnie, ale są wizualnie połączone w logiczną grupę. Jest to szczególnie ważne dla ekranów formularzy, gdzie użytkownik powinien szybko orientować się w strukturze wprowadzanych danych.
System automatycznie zarządza odstępami między sekcjami: odległość między Section w iOS wynosi 16–20 punktów, między elementami wewnątrz Section — 0 (separator między wierszami). Deweloper nie może zmienić tych odstępów przez modyfikatory padding — są one kontrolowane przez system w celu zapewnienia jednolitego wyglądu.
Section przyjmuje dwa opcjonalne parametry: header — nagłówek grupy, oraz footer — tekst objaśniający pod grupą. Nagłówek wyświetla się nad elementami sekcji pogrubioną czcionką w stylu caption, stopka — mniejszą czcionką w szarym kolorze. Oba parametry przyjmują dowolną SwiftUI View, nie tylko Text.
Nagłówek Section pomaga użytkownikowi zrozumieć, do której kategorii należą elementy wewnątrz grupy. Na przykład na ekranie ustawień nagłówki „Powiadomienia”, „Prywatność” i „Konto” natychmiast orientują użytkownika. Stopka jest odpowiednia do wyjaśnień: „Wyłącz powiadomienia na czas spotkania” lub „Hasło musi zawierać co najmniej 8 znaków”. Stopka automatycznie zawija się na kilka wierszy w razie potrzeby.
Section(
header: Text("Bezpieczeństwo konta"),
footer: Text("Użyj silnego hasła składającego się z co najmniej 8 znaków.")
) {
SecureField("Current password", text: $currentPassword)
SecureField("New password", text: $newPassword)
}
W przykładzie Section ma nagłówek „Bezpieczeństwo konta” i stopkę z poradą dotyczącą bezpieczeństwa hasła. Użytkownik widzi nagłówek jako etykietę sekcji, wypełnia dwa pola i od razu czyta ostrzeżenie pod nimi. Taka struktura poprawia UX, ponieważ wszystkie informacje o sekcji znajdują się na jednym ekranie bez konieczności przechodzenia do osobnej pomocy.
Section działa zarówno wewnątrz Form, jak i List, ale wygląd wizualny różni się. W Form Section wyświetla się jako blok z zaokrąglonymi rogami i systemowym tłem, oddzielony od sąsiednich sekcji odstępami. W List Section może używać stylu plain — bez tła i zaokrągleń, lub inset-grouped — z zaokrąglonymi blokami, podobnie jak Form.
Wybór kontenera wpływa na styl Section. Umieszczenie Section z tą samą zawartością wewnątrz Form i List ze stylem .insetGrouped da identyczny wynik. Jednak Form dodaje systemowe odstępy i domyślnie używa grouped-stylu, podczas gdy List wymaga jawnego określenia stylu przez modyfikator .listStyle(.insetGrouped).
| Kontener | Section domyślnie | Dostępne style |
|---|---|---|
| Form | InsetGrouped z zaokrąglonymi rogami | .grouped (tylko Form) |
| List | Plain — bez tła sekcji | .plain, .inset, .insetGrouped, .sidebar |
Aby uzyskać identyczny wygląd w List, użyj .listStyle(.insetGrouped). Ten styl imituje wygląd Form i nadaje się do ekranów ustawień zbudowanych na List. Do standardowych list danych używaj .plain — bez wyróżniania sekcji, z cienkimi separatorami między wierszami.
Section może zawierać dynamiczną liczbę elementów przez ForEach. Pozwala to tworzyć grupy z powtarzającymi się elementami, zachowując nagłówek i stopkę dla całej grupy. ForEach wewnątrz Section iteruje kolekcję danych i tworzy widoki potomne dla każdego elementu, nie naruszając struktury sekcji.
Dynamiczne sekcje są przydatne na ekranach ustawień ze zmienną liczbą opcji: lista języków do wyboru, lista podłączonych urządzeń lub lista subskrypcji push. Nagłówek sekcji pozostaje statyczny, a zawartość zmienia się w zależności od danych.
struct DynamicSectionView: View {
let categories = ["Work", "Personal", "Finance", "Health"]
@State private var selected = Set<String>()
var body: some View {
Form {
Section(header: Text("Kategorie"),
footer: Text("Wybierz preferowane kategorie")) {
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("Wybrano: \(selected.count) kategorii")
.foregroundStyle(.secondary)
}
}
}
}
W tym przykładzie ForEach generuje Toggle dla każdej kategorii z tablicy categories. Nagłówek i stopka sekcji są ustawione raz i dotyczą całej grupy. Druga sekcja wyświetla liczbę wybranych kategorii — nie zależy od ForEach i pozostaje statyczna. Takie podejście pozwala tworzyć elastyczne formularze, gdzie nagłówek i stopka kontekstualizują grupę dynamicznych elementów.
Przyjrzyjmy się pełnemu przykładowi ekranu profilu z użyciem Section do grupowania danych. Formularz zawiera trzy sekcje: informacje o użytkowniku, ustawienia prywatności i statystyki. Każda sekcja używa własnego nagłówka, a ostatnia — stopki z informacjami podsumowującymi.
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("Info o profilu")) {
TextField("Display name", text: $displayName)
TextField("Bio", text: $bio, axis: .vertical)
.lineLimit(3)
}
Section(header: Text("Prywatność")) {
Toggle("Public profile", isOn: $isProfilePublic)
Toggle("Show email", isOn: $showEmail)
.disabled(!isProfilePublic)
}
Section(header: Text("Statystyki"),
footer: Text("Ostatnia aktualizacja dzisiaj o 14:30")) {
LabeledContent("Posts", value: "42")
LabeledContent("Followers", value: "1,280")
LabeledContent("Following", value: "346")
}
}
.navigationTitle("Profile")
}
}
Trzy Section wyraźnie oddzielają bloki funkcjonalne: edytowalne pola profilu, przełączniki prywatności i statystyki. Druga sekcja demonstruje walidację: Toggle „Pokaż e-mail” jest wyłączony, dopóki profil nie jest publiczny. Stopka trzeciej sekcji pokazuje czas ostatniej aktualizacji — przykład użycia stopki do dodatkowych informacji kontekstowych. LabeledContent to standardowy komponent SwiftUI do wyświetlania pary „klucz-wartość” w Form.
Section(
header: HStack {
Image(systemName: "bell.fill")
.foregroundStyle(.blue)
Text("Powiadomienia")
.font(.headline)
},
footer: Text("Zarządzaj powiadomieniami push i e-mail")
) {
Toggle("Push notifications", isOn: $push)
Toggle("Email notifications", isOn: $email)
Stepper("Quiet hours: \(quietStart) — \(quietEnd)",
value: $quietStart,
in: 0...23)
}
Ten przykład pokazuje, że header może być dowolną SwiftUI View. Użycie HStack z Image i Text pozwala dodać ikonę obok nagłówka, czyniąc sekcję wizualnie bardziej wyrazistą. Niestandardowe nagłówki są przydatne do wyróżniania ważnych sekcji w interfejsie: ustawienia powiadomień, funkcje płatne lub sekcje z ostrzeżeniami. Nie należy jednak nadużywać niestandardowych nagłówków — na każdym ekranie wystarczy 1–2 sekcji z nietypowym wyglądem, aby zachować spójność interfejsu.
Często zadawane pytania
Nie, Section nie obsługuje zagnieżdżania w SwiftUI. Próba umieszczenia Section wewnątrz innej Section powoduje błąd kompilacji. Do hierarchicznego grupowania użyj List z OutlineGroup lub DisclosureGroup wewnątrz Section.
Odstępy między Section są zarządzane przez system i nie można ich zmienić przez modyfikatory padding. W iOS odległość między sekcjami wynosi 16–20 punktów i jest zgodna z HIG. Jedynym sposobem wpływania na odstępy jest użycie niestandardowego ListStyle, ale nie jest to zalecane.
Group to niewidoczny kontener do grupowania elementów bez wizualnego formatowania. Section dodaje nagłówek, stopkę, odstępy i blok wizualny. Group jest używany do warunkowego renderowania, Section — do strukturyzowania interfejsu.
Tak, Section automatycznie dodaje etykiety dostępności. Nagłówek sekcji staje się nagłówkiem dostępności grupy, a stopka — podpowiedzią dostępności. VoiceOver odczytuje nagłówek przed wejściem do sekcji, co poprawia nawigację dla użytkowników z ograniczeniami.
Nie, Section działa tylko wewnątrz Form lub List. Użycie Section poza tymi kontenerami powoduje błąd kompilacji. Do grupowania elementów w VStack lub ScrollView użyj Group lub niestandardowych widoków z ręcznym ustawieniem odstępów.
Podsumowanie
Opracujemy aplikację mobilną pod klucz
IT Sectr tworzy aplikacje na iOS i Androida dla startupów i firm od 2017 roku. Doradzimy Ci i zaproponujemy najlepsze rozwiązanie.
Przeczytaj również