Form no SwiftUI é um componente contentor para construir interfaces estruturadas de configurações e entrada de dados, seguindo o design do Settings no iOS. O componente agrupa automaticamente os controlos em secções com espaçamento e estilos do sistema, libertando o programador do ajuste manual de separadores e cores. De acordo com a Documentação Apple Developer (2025), Form adapta a sua aparência a cada plataforma — desde tabelas agrupadas no iOS até listas padrão no macOS — mantendo uma API unificada.
Principais pontos
Form é um contentor especializado do SwiftUI projetado para criar formulários de entrada e ecrãs de configurações. Ele herda o comportamento do List, mas adiciona estilos específicos da plataforma: no iOS, o Form exibe-se como uma tabela agrupada com cantos arredondados nas secções; no macOS, aparece como uma lista padrão do sistema com caixas de seleção e controlos.
Ao contrário do layout manual com VStack e HStack, o Form organiza automaticamente o espaçamento entre elementos, adiciona separadores e adapta a sua aparência ao tema do sistema — claro ou escuro. O programador descreve apenas a estrutura lógica: Section para agrupar e os controlos dentro. O próprio formulário decide como dispor visualmente o Picker, Toggle ou Stepper numa plataforma específica.
O Form suporta todos os elementos de entrada padrão do SwiftUI: TextField para texto, SecureField para palavras-passe, Picker para seleção de lista, Toggle para ligar/desligar, Slider para intervalos, Stepper para valores incrementais e DatePicker para datas. Cada elemento obtém automaticamente um estilo correspondente às HIG (Human Interface Guidelines) da Apple na plataforma de destino.
Apesar da sua semelhança visual, Form e List resolvem tarefas diferentes. List é um contentor universal para exibir listas de dados com capacidade de scroll, ações de deslize e edição de linhas. Form é um contentor especializado para entrada de dados e configurações, otimizado para estilos de controlo do sistema.
List é adequado para exibir dados dinâmicos: feeds de notícias, chats, catálogos de produtos. Form é para ecrãs estáticos com um conjunto previsível de campos: perfil de utilizador, configurações da aplicação, formulário de registo. A diferença chave: os elementos do Form podem ser controlos interativos, enquanto as linhas do List geralmente exibem dados e respondem ao toque com navegação ou ação.
| Parâmetro | Form | List |
|---|---|---|
| Finalidade | Entrada de dados, configurações | Exibição de listas |
| Estilo de secções | Grouped (iOS), sistema (macOS) | Plain ou Grouped |
| Controlos | Picker, Toggle, Slider, Stepper | Limitados (botão) |
| Dados dinâmicos | Limitado (ForEach dentro de Section) | Suporte completo |
| Ações de deslize | Sim, swipeActions | Sim, swipeActions |
De acordo com as Apple Human Interface Guidelines (2025), o Form deve ser usado para ecrãs de configurações e entrada onde existam de 3 a 20 controlos num ecrã e dividi-los em secções melhora a usabilidade.
Section é o bloco de construção principal do Form, permitindo agrupar elementos logicamente relacionados. Cada Section pode ter um cabeçalho, rodapé e qualquer número de controlos no interior. O sistema adiciona automaticamente espaçamento entre secções e envolve cada uma num bloco visual com cantos arredondados.
Usar Section é fundamental para a legibilidade do formulário: elementos agrupados por significado são mais fáceis de processar pelo utilizador. Por exemplo, num ecrã de configurações de perfil, podem separar-se «Dados pessoais», «Notificações» e «Segurança» em secções individuais. Cada secção pode conter um rodapé com texto explicativo que o sistema exibe num tipo de letra mais pequeno abaixo do grupo de elementos.
Form {
Section(header: Text("Perfil")) {
TextField("Nome", text: $name)
TextField("Email", text: $email)
}
Section(header: Text("Notificações"),
footer: Text("Desativar durante reuniões")) {
Toggle("Push notifications", isOn: $pushEnabled)
Toggle("Email notifications", isOn: $emailEnabled)
}
}
No exemplo, a primeira secção «Profile» contém dois campos de texto sem rodapé, a segunda secção «Notifications» contém dois interruptores com uma explicação abaixo do grupo. O rodapé adiciona automaticamente espaçamento e usa o estilo de tipo de letra caption. Uma Section pode ter um rodapé sem cabeçalho ou um cabeçalho sem rodapé.
O Form suporta todos os elementos de entrada padrão do SwiftUI. Picker no Form exibe-se automaticamente como uma linha de navegação com transição para um ecrã de seleção separado no iOS. Toggle aparece como uma linha com um interruptor alinhado à direita. TextField obtém o estilo de entrada do sistema com um espaço reservado.
Para valores numéricos, usam-se Stepper (alteração incremental) e Slider (alteração suave num intervalo). DatePicker suporta vários modos: date, time, dateAndTime. ColorPicker está disponível para seleção de cor. Cada elemento adapta-se à plataforma sem código adicional — no iOS, os controlos usam estilos nativos do UIKit; no macOS, do AppKit.
| Elemento | Finalidade | Estilo no Form |
|---|---|---|
| TextField | Entrada de texto | Linha com espaço reservado |
| SecureField | Entrada de palavra-passe | Linha com caracteres ocultos |
| Picker | Seleção de lista | NavigationLink para ecrã de seleção |
| Toggle | Ligar/Desligar | Linha com interruptor |
| Slider | Intervalo de valores | Controlo deslizante horizontal |
| DatePicker | Seleção de data/hora | Estilo compacto ou de roda |
Para controlos personalizados dentro do Form, pode usar-se qualquer SwiftUI View — elas herdam o comportamento padrão da secção. No entanto, recomenda-se usar elementos do sistema, pois garantem conformidade com as HIG e suportam Acessibilidade (VoiceOver, Dynamic Type) sem configuração adicional.
Vamos criar um ecrã de registo usando Form. O formulário contém quatro secções: dados pessoais, seleção de função, configurações de subscrição e um botão de envio. Usa-se Section para agrupar e controlos padrão do 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("Informações pessoais")) {
TextField("Name", text: $name)
TextField("Email", text: $email)
.keyboardType(.emailAddress)
}
Section(header: Text("Função")) {
Picker("Select role", selection: $role) {
ForEach(roles, id: \.self) { role in
Text(role).tag(role)
}
}
}
Section {
Toggle("Agree to terms", isOn: $agreedToTerms)
}
Section {
Button("Registar") {
submitForm()
}
.disabled(!agreedToTerms)
}
}
.navigationTitle("Registration")
}
}
private func submitForm() { }
}
O formulário está dividido em quatro Section: dados pessoais com dois campos de texto, seleção de função através de Picker, aceitação de termos através de Toggle e um botão de registo. O botão está desativado até o utilizador aceitar os termos — isto é um exemplo de validação dentro do Form. NavigationStack adiciona um título e permite que o Picker abra um ecrã de seleção separado no 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("Aparência")) {
Toggle("Dark mode", isOn: $isDarkMode)
Slider(value: $volume, in: 0...1) {
Text("Volume")
}
}
Section(header: Text("Lembretes"),
footer: Text("Receberá uma notificação no horário selecionado")) {
DatePicker("Remind at",
selection: $reminderDate,
displayedComponents: .hourAndMinute)
}
Section {
NavigationLink("Advanced Settings",
destination: AdvancedSettingsView())
}
}
.navigationTitle("Settings")
}
}
}
Este exemplo demonstra uma combinação de Slider, DatePicker e NavigationLink dentro do Form. DatePicker usa o modo hourAndMinute para exibir apenas a hora. NavigationLink na última secção cria uma transição para um ecrã de configurações avançadas — um padrão comum para interfaces estilo Settings. Os cabeçalhos e rodapés das secções tornam o formulário autodocumentado: o utilizador compreende imediatamente a que grupo pertence cada controlo.
Perguntas frequentes
Form é otimizado para entrada de dados e configurações: os controlos obtêm estilos do sistema, as secções obtêm cantos arredondados e espaçamento. List é um contentor universal para exibição de dados. Form é adequado para ecrãs de configurações, List é para chats, feeds, catálogos.
Sim, Picker dentro de Form exibe-se automaticamente como uma linha com o valor selecionado e um NavigationLink para seleção de lista no iOS. No macOS, Picker aparece como uma lista suspensa ou grupo de rádio dependendo do estilo. A adaptação ocorre sem código adicional.
Qualquer SwiftUI View pode ser colocada dentro de Form ou Section. Para controlos personalizados, recomenda-se herdar o espaçamento padrão da secção e suportar Dynamic Type através de tipos de letra do sistema. Evite tamanhos e cores fixos para que o formulário seja exibido corretamente em todos os dispositivos.
Sim, o Form é automaticamente envolvido num ScrollView se o conteúdo ultrapassar a altura do ecrã. Não é necessário adicionar ScrollView manualmente — o sistema determina se é necessário scroll. Para formulários que não devem ter scroll, use VStack com altura fixa.
O Form no iOS suporta dois estilos através do modificador .formStyle(.grouped) — a vista agrupada padrão com secções arredondadas. No macOS, está disponível .formStyle(.columns) com disposição de várias colunas. O estilo aplica-se a todo o Form de uma vez e altera a representação visual de todos os elementos internos.
Resumo
Vamos desenvolver um aplicativo móvel chave na mão
A IT Sectr cria aplicativos para iOS e Android para startups e empresas desde 2017. Nós vamos aconselhá-lo e propor a melhor solução.
Leia também