Form w SwiftUI — komponent kontenerowy do budowania strukturalnych interfejsów ustawień i wprowadzania danych, wzorowany na projekcie Settings w iOS. Komponent automatycznie grupuje elementy sterujące w sekcje z systemowymi odstępami i stylami, zwalniając programistę z ręcznej kalibracji separatorów i kolorów. Według Apple Developer Documentation (2025), Form dostosowuje wygląd do każdej platformy — od grupowanych tabel na iOS po standardowe listy na macOS — zachowując wspólne API.
Najważniejsze
Form to wyspecjalizowany kontener SwiftUI przeznaczony do tworzenia formularzy wprowadzania danych i ekranów ustawień. Dziedziczy zachowanie List, ale dodaje style platformowe: na iOS Form jest wyświetlany jako tabela grupowana z zaokrąglonymi rogami sekcji, na macOS — jako standardowa systemowa lista z polami wyboru i kontrolkami.
W przeciwieństwie do ręcznego układu z VStack i HStack, Form automatycznie rozkłada odstępy między elementami, dodaje separatory i dostosowuje wygląd do motywu systemowego — jasnego lub ciemnego. Programista opisuje tylko logiczną strukturę: Section do grupowania i elementy sterujące w środku. Form sam decyduje, jak wizualnie rozmieścić Picker, Toggle lub Stepper na danej platformie.
Form obsługuje wszystkie standardowe elementy wprowadzania SwiftUI: TextField do tekstu, SecureField do haseł, Picker do wyboru z listy, Toggle do włączania/wyłączania, Slider do zakresów, Stepper do wartości krokowych i DatePicker do daty. Każdy element automatycznie otrzymuje styl zgodny z HIG (Human Interface Guidelines) firmy Apple na docelowej platformie.
Mimo zewnętrznego podobieństwa, Form i List rozwiązują różne zadania. List to uniwersalny kontener do wyświetlania przewijanych list danych z możliwością akcji przesunięcia i edycji wierszy. Form to wyspecjalizowany kontener do wprowadzania danych i ustawień, zoptymalizowany pod systemowe style kontrolek.
List sprawdza się do wyświetlania dynamicznych danych: kanałów wiadomości, czatów, katalogów produktów. Form — do statycznych ekranów z przewidywalnym zestawem pól: profil użytkownika, ustawienia aplikacji, ankieta rejestracyjna. Kluczowa różnica: elementy Form mogą być interaktywnymi kontrolkami, podczas gdy wiersze List najczęściej wyświetlają dane i reagują na dotknięcie nawigacją lub akcją.
| Parametr | Form | List |
|---|---|---|
| Przeznaczenie | Wprowadzanie danych, ustawienia | Wyświetlanie list |
| Styl sekcji | Grouped (iOS), systemowy (macOS) | Plain lub Grouped |
| Kontrolki | Picker, Toggle, Slider, Stepper | Ograniczone (przycisk) |
| Dane dynamiczne | Ograniczone (ForEach wewnątrz Section) | Pełne wsparcie |
| Akcje przesunięcia | Tak, swipeActions | Tak, swipeActions |
Według Apple Human Interface Guidelines (2025), Form należy używać do ekranów ustawień i wprowadzania, gdzie na jednym ekranie znajduje się od 3 do 20 elementów sterujących, a podział na sekcje poprawia percepcję.
Section to podstawowy element konstrukcyjny Form, umożliwiający grupowanie logicznie powiązanych elementów. Każda Section może mieć nagłówek, stopkę i dowolną liczbę kontrolek wewnątrz. System automatycznie dodaje odstępy między sekcjami i opakowuje każdą w wizualny blok z zaokrąglonymi rogami.
Używanie Section jest kluczowe dla czytelności formularza: elementy pogrupowane według znaczenia są łatwiej odbierane przez użytkownika. Na przykład na ekranie ustawień profilu można wyodrębnić do osobnych sekcji „Dane osobowe", „Powiadomienia" i „Bezpieczeństwo". Każda sekcja może zawierać stopkę z tekstem wyjaśniającym, który system wyświetla mniejszą czcionką pod grupą elementów.
Form {
Section(header: Text("Profil")) {
TextField("Nazwa", text: $name)
TextField("Email", text: $email)
}
Section(header: Text("Powiadomienia"),
footer: Text("Wyłącz podczas spotkań")) {
Toggle("Push notifications", isOn: $pushEnabled)
Toggle("Email notifications", isOn: $emailEnabled)
}
}
W przykładzie pierwsza sekcja „Profile" zawiera dwa pola tekstowe bez stopki, druga sekcja „Notifications" — dwa przełączniki z wyjaśnieniem pod grupą. Stopka automatycznie dodaje odstęp i używa stylu czcionki caption. Section może zawierać stopkę bez nagłówka lub nagłówek bez stopki.
Form obsługuje wszystkie standardowe elementy wprowadzania SwiftUI. Picker w Form jest automatycznie wyświetlany jako wiersz nawigacyjny z przejściem na osobny ekran wyboru na iOS. Toggle jest wyświetlany jako wiersz z przełącznikiem wyrównanym do prawej krawędzi. TextField otrzymuje systemowy styl wprowadzania z tekstem zastępczym (placeholder).
Do wartości liczbowych używa się Stepper (zmiana krokowa) i Slider (płynna zmiana w zakresie). DatePicker obsługuje kilka trybów: date, time, dateAndTime. Do wyboru koloru dostępny jest ColorPicker. Każdy element dostosowuje się do platformy bez dodatkowego kodu — na iOS kontrolki używają natywnych stylów UIKit, na macOS — AppKit.
| Element | Przeznaczenie | Styl w Form |
|---|---|---|
| TextField | Wprowadzanie tekstu | Wiersz z tekstem zastępczym |
| SecureField | Wprowadzanie hasła | Wiersz z ukrytymi znakami |
| Picker | Wybór z listy | NavigationLink do ekranu wyboru |
| Toggle | Włącz/Wyłącz | Wiersz z przełącznikiem |
| Slider | Zakres wartości | Poziomy suwak |
| DatePicker | Wybór daty/godziny | Styl kompaktowy lub kołowy |
Do niestandardowych kontrolek wewnątrz Form można używać dowolnych widoków SwiftUI — dziedziczą one standardowe zachowanie sekcji. Jednak zaleca się trzymanie się elementów systemowych, ponieważ gwarantują one zgodność z HIG i wspierają Accessibility (VoiceOver, Dynamic Type) bez dodatkowej konfiguracji.
Rozważmy utworzenie ekranu rejestracji z użyciem Form. Formularz zawiera cztery sekcje: dane osobowe, wybór roli, ustawienia subskrypcji i przycisk wysyłania. Używane są Section do grupowania i standardowe kontrolki 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("Dane osobowe")) {
TextField("Name", text: $name)
TextField("Email", text: $email)
.keyboardType(.emailAddress)
}
Section(header: Text("Rola")) {
Picker("Select role", selection: $role) {
ForEach(roles, id: \.self) { role in
Text(role).tag(role)
}
}
}
Section {
Toggle("Agree to terms", isOn: $agreedToTerms)
}
Section {
Button("Zarejestruj się") {
submitForm()
}
.disabled(!agreedToTerms)
}
}
.navigationTitle("Registration")
}
}
private func submitForm() { }
}
Formularz jest podzielony na cztery Section: dane osobowe z dwoma polami tekstowymi, wybór roli przez Picker, zgodę na warunki przez Toggle i przycisk rejestracji. Przycisk jest wyłączony, dopóki użytkownik nie zgodzi się na warunki — to przykład walidacji wewnątrz Form. NavigationStack dodaje nagłówek i umożliwia Picker otwieranie osobnego ekranu wyboru na 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("Wygląd")) {
Toggle("Dark mode", isOn: $isDarkMode)
Slider(value: $volume, in: 0...1) {
Text("Głośność")
}
}
Section(header: Text("Przypomnienia"),
footer: Text("Otrzymasz powiadomienie o wybranej godzinie")) {
DatePicker("Remind at",
selection: $reminderDate,
displayedComponents: .hourAndMinute)
}
Section {
NavigationLink("Advanced Settings",
destination: AdvancedSettingsView())
}
}
.navigationTitle("Settings")
}
}
}
Ten przykład pokazuje kombinację Slider, DatePicker i NavigationLink wewnątrz Form. DatePicker używa trybu hourAndMinute do wyświetlania tylko godziny. NavigationLink w ostatniej sekcji tworzy przejście na ekran rozszerzonych ustawień — powszechny wzorzec dla interfejsów w stylu Settings. Nagłówki i stopki sekcji czynią formularz samodokumentującym się: użytkownik od razu rozumie, do której grupy należy każdy element sterujący.
Najczęściej zadawane pytania
Form jest zoptymalizowany do wprowadzania danych i ustawień: elementy sterujące otrzymują systemowe style, sekcje — zaokrąglone rogi i odstępy. List to uniwersalny kontener do wyświetlania danych. Form nadaje się do ekranów ustawień, List — do czatów, kanałów, katalogów.
Tak, Picker wewnątrz Form jest automatycznie wyświetlany jako wiersz z wybraną wartością i NavigationLink do wyboru z listy na iOS. Na macOS Picker jest wyświetlany jako lista rozwijana lub grupa przycisków opcji w zależności od stylu. Adaptacja następuje bez dodatkowego kodu.
Każdy widok SwiftUI może być umieszczony wewnątrz Form lub Section. Dla niestandardowych kontrolek zaleca się dziedziczenie standardowych odstępów sekcji i wspieranie Dynamic Type przez systemowe czcionki. Unikaj stałych rozmiarów i kolorów, aby formularz był poprawnie wyświetlany na wszystkich urządzeniach.
Tak, Form jest automatycznie opakowywany w ScrollView, jeśli zawartość przekracza wysokość ekranu. Nie trzeba dodawać ScrollView ręcznie — system sam określa potrzebę przewijania. W przypadku formularzy, które nie powinny się przewijać, użyj VStack ze stałą wysokością.
Form na iOS obsługuje dwa style przez modyfikator .formStyle(.grouped) — standardowy widok grupowany z zaokrąglonymi sekcjami. Dla macOS dostępny jest .formStyle(.columns) z układem wielokolumnowym. Styl jest stosowany do całego Form naraz i zmienia wizualną reprezentację wszystkich elementów wewnątrz.
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ż