SwiftUI: o que é, conceitos-chave e View Protocol

Autor: IT Sectr Publicado: 2026-04-30 Tempo de leitura: 8 min

SwiftUI é um framework declarativo da Apple para construir interfaces de utilizador em todas as plataformas do ecossistema. Em vez de descrever passos de forma imperativa, o programador declara como a interface deve ser e o SwiftUI gere a sua renderização e atualização. De acordo com a Apple Developer Documentation (2025), o SwiftUI suporta iOS 15+, iPadOS 15+, macOS 12+, watchOS 8+ e tvOS 15+ e utiliza o View Protocol como bloco de construção base para todos os componentes de interface.

Principais conclusões

  • SwiftUI é um framework declarativo da Apple onde o programador descreve a interface e as atualizações são feitas automaticamente.
  • View Protocol com a propriedade body é a base de qualquer componente UI do SwiftUI, devolvendo uma descrição do ecrã através de composição de vistas.
  • Property Wrappers — @State, @Binding, @ObservedObject, @StateObject — gerem o estado e acionam o redesenho quando os dados mudam.
  • NavigationStack (iOS 16+) é uma API de navegação moderna com rotas type-safe e transições declarativas.
  • Modifier é uma cadeia de chamadas para personalizar a aparência e o comportamento das vistas sem herança de classes.

O que é SwiftUI?

SwiftUI é um framework declarativo apresentado pela Apple em 2019 para substituir o UIKit em novos projetos. Em vez de criar manualmente instâncias de UIView e adicioná-las à hierarquia, o programador descreve a interface através de estruturas que cumprem o protocolo View. O SwiftUI calcula automaticamente a diferença entre o estado atual e o novo e redesenha apenas as partes alteradas usando o seu próprio motor de renderização.

O framework é escrito em Swift usando value semantics (estruturas, não classes), tornando os componentes UI leves e thread-safe. Ao contrário do UIKit, onde UIViewController pode pesar 200+ bytes devido ao runtime Objective-C, uma SwiftUI View é simplesmente uma estrutura de poucos bytes. Isto é especialmente importante para o watchOS com a sua memória limitada.

Multiplataforma SwiftUI

A mesma descrição de View funciona no iPhone, iPad, Mac, Apple Watch, Apple TV e Apple Vision Pro. O SwiftUI adapta a interface à plataforma: gestos táteis no iOS, combinações de teclado no macOS, deslocamento com Digital Crown no watchOS. Isto reduz o tempo de desenvolvimento para empresas que lançam aplicações em múltiplas plataformas Apple, mas requer configuração adicional para elementos específicos de cada plataforma.

View Protocol e o corpo da vista

Em SwiftUI, cada ecrã é uma estrutura que implementa o protocolo View com um único requisito: uma propriedade computada body do tipo some View. A palavra-chave some (opaque type) oculta o tipo concreto da vista, permitindo ao SwiftUI otimizar a renderização. Dentro de body, o programador combina componentes prontos — Text, Image, Button, List — usando ViewBuilder, que monta várias vistas numa só.

swift
struct GreetingView: View {
    let name: String

    var var body: some View {
        VStack {
            Text("Olá, \(name)!")
                .font(.title)
                .foregroundColor(.blue)
            Image(systemName: "hand.wave")
                .imageScale(.large)
        }
        .padding()
    }
}

No exemplo, VStack (stack vertical) contém Text e Image. O valor de name é passado através do inicializador da estrutura — é assim que o DI (Dependency Injection) funciona no SwiftUI sem contentores DI externos. Cada modificador devolve uma nova vista com a alteração aplicada, sem mutar o original. Isto é possível graças à imutabilidade dos value types.

ViewBuilder e condicionais

ViewBuilder é um result builder anotado com @resultBuilder que monta até 10 vistas numa só. Dentro de body podem usar-se if/else, switch e ForEach sem invólucros adicionais. ForEach trabalha com elementos Identifiable — a cada vista é atribuído um id único para uma animação correta durante inserção/remoção.

Gestão de estado: @State, @Binding, @ObservedObject

Em SwiftUI, o estado determina que conteúdo é exibido no ecrã. Quando o estado muda, o SwiftUI recria o body da vista dependente e compara o resultado com o anterior usando um algoritmo de diff. Para armazenar o estado, usam-se property wrappers — cada um resolve a sua tarefa específica: estado local, ligação com uma vista filha ou modelo de dados externo.

swift
struct CounterView: View {
    @State private var count = 0

    var var body: some View {
        VStack {
            Text("Contador: \(count)")
            Button("Incrementar") {
                count += 1
            }
        }
    }
}

class UserViewModel: ObservableObject {
    @Published var name = ""
    @Published var age = 0
}

@State armazena um valor local simples (Int, String, Bool) dentro da estrutura View. O SwiftUI move a memória da estrutura para um armazenamento separado — portanto, uma propriedade com @State pode ser mutada mesmo que View seja um value type. @ObservableObject é para classes com propriedades @Published, cujas alterações notificam automaticamente o SwiftUI da necessidade de redesenhar.

@Binding e ligação pai-filho

@Binding cria uma ligação bidirecional a uma fonte de dados localizada na vista pai. O pai passa $variable (projected value), e o filho lê e escreve o valor através do binding. Isto permite mover a entrada de texto ou um interruptor para um componente separado mantendo o estado no pai. Sem @Binding, cada alteração exigiria um closure de callback para passar o novo valor para cima.

Antes do iOS 16, a navegação em SwiftUI era construída sobre NavigationView — uma API legada com comportamento complexo no iPad (split view, coluna dupla). A partir do iOS 16, a Apple recomenda NavigationStack — uma alternativa simplificada com rotas type-safe. O programador define um enum de rotas possíveis, e o NavigationStack gere automaticamente a pilha de ecrãs com suporte para deep links e retorno à raiz.

swift
enum Route: Hashable {
    case detail(id: Int)
    case settings
}

struct ContentView: View {
    var var body: some View {
        NavigationStack {
            List {
                NavigationLink("Ecrã de detalhe",
                               value: Route.detail(id: 42))
                NavigationLink("Definições",
                               value: Route.settings)
            }
            .navigationDestination(for: Route.self) { route in
                switch route {
                case .detail(let id): DetailView(id: id)
                case .settings: SettingsView()
                }
            }
        }
    }
}

Rotas em conformidade com Hashable permitem usar qualquer tipo de dados para passar parâmetros. navigationDestination(for:destination:) associa o tipo de rota à vista de destino. A vantagem sobre a navegação UIKit é que não é necessário redesenhar ao adicionar uma nova rota: basta adicionar um case ao enum e um handler no switch. Os deep links são tratados através de processDeepLink no NavigationStack.

Navegação programática

Para navegação programática (após login, temporizador ou resposta do servidor), usa-se @State com o inicializador NavigationLink: NavigationLink(isActive: $isActive). Quando isActive = true, a transição ocorre sem toque do utilizador. Uma alternativa é o binding do array $path no NavigationStack: $path.append(Route.detail(id: 1)).

View Modifier — personalização da aparência

Modifier é um método que devolve uma cópia modificada da vista. Ao contrário do UIKit, onde a configuração de propriedades é feita através de mutação de uma vista existente, o SwiftUI cria um novo valor com a alteração aplicada. O encadeamento de modificadores constrói a interface final a partir de transformações sequenciais: fonte → padding → cor → sombra → gesto.

A Apple fornece mais de 200 modificadores integrados. Os mais comuns: .font(), .foregroundColor(), .padding(), .background(), .cornerRadius(), .shadow(), .opacity(), .offset(). A ordem dos modificadores é importante: .padding() antes de .background() preenche a área com padding, depois — apenas a área interior. Modificadores personalizados são criados através do protocolo ViewModifier.

Modificadores condicionais e animação

Os modificadores podem ser aplicados condicionalmente através do operador ternário: .foregroundColor(isError ? .red : .primary). Para animação, usa-se .animation(.easeInOut, value: state) — o modificador de animação é vinculado a uma propriedade de estado específica. Quando esta propriedade muda, o SwiftUI anima a transição entre o valor antigo e o novo. A animação funciona com opacity, offset, scale, rotation, tamanho e cor — cada propriedade tem um AnimatableParameter correspondente.

Para animações personalizadas, estão disponíveis .transition (aparecimento/desaparecimento) e .matchedGeometryEffect (transição suave de um elemento entre dois contentores). O último é usado para hero animation em listas: um ícone numa célula de lista transforma-se suavemente numa imagem grande no ecrã de detalhe.

SwiftUI vs UIKit: comparação de abordagens

A escolha entre SwiftUI e UIKit é um dos primeiros dilemas do programador iOS. Ambos os frameworks são suportados pela Apple, mas resolvem o problema de construção de interfaces de formas fundamentalmente diferentes: SwiftUI declarativamente, UIKit imperativamente. A diferença manifesta-se na gestão de estado, navegação, desempenho e compatibilidade.

AspetoSwiftUIUIKit
AbordagemDeclarativa: o que mostrarImperativa: como construir
EstadoProperty Wrappers, redesenho automáticoManual: reloadData, setNeedsLayout
Código UICompacto, cadeias de modificadoresVerboso, NSCoder/Storyboard/restrições
DesempenhoAlto no iOS 17+, algoritmo de diffPico no iOS 12–16, controlo direto
Versão mínimaiOS 15+ (suporte completo)iOS 2+ (todas as versões)

Para novos projetos com versão mínima iOS 17, a Apple recomenda SwiftUI como framework principal. O UIKit continua necessário para interfaces que requerem controlo fino sobre a renderização (UICollectionViewLayout personalizado, cenas CAAnimation complexas) ou suporte para iOS 12–14. Muitos projetos usam uma abordagem híbrida: o SwiftUI através de UIHostingController é incorporado numa app UIKit, e UIViewRepresentable permite usar componentes UIKit dentro da hierarquia SwiftUI.

Perguntas frequentes

Posso usar SwiftUI e UIKit no mesmo projeto?

Sim, através de UIHostingController (SwiftUI no UIKit) e UIViewRepresentable (UIKit no SwiftUI). É uma abordagem híbrida, popular durante a migração.

Com que versão do iOS devo começar um projeto SwiftUI?

O iOS 17 oferece funcionalidade completa: NavigationStack, Observation framework, Swift Charts. O iOS 15 é o limiar mínimo para produção.

Porque é que o SwiftUI às vezes não atualiza a interface?

A causa mais frequente é alterar uma propriedade @Published numa thread secundária. O ObservableObject deve enviar as alterações no main actor: @MainActor class ViewModel.

Como lidar com debounce ao premir um botão no SwiftUI?

Use .debounce através do Combine: Button.publisher(for: .tap) .debounce(for: .seconds(0.3), scheduler: RunLoop.main).

O SwiftUI suporta gestos personalizados?

Sim, através dos modificadores Gesture: DragGesture, LongPressGesture, MagnificationGesture, RotationGesture. Combine-os usando .simultaneousGesture() e .sequenced().

Resumo

  • SwiftUI é um framework declarativo da Apple onde a interface é descrita como uma composição de estruturas View com property wrappers para gestão de estado.
  • View Protocol com a propriedade computada body é o ponto de entrada único para qualquer vista. ViewBuilder monta até 10 vistas numa sem contentores extras.
  • @State, @Binding e @ObservedObject cobrem todos os cenários de gestão de dados: estado local, ligação pai-filho e modelos externos.
  • NavigationStack com rotas enum type-safe substituiu o NavigationView, adicionando suporte para deep links e navegação programática.
  • Modifier é um padrão chave do SwiftUI que permite personalizar a aparência das vistas através de uma cadeia de chamadas sem herança.
  • SwiftUI e UIKit coexistem através de UIHostingController e UIViewRepresentable, permitindo uma migração gradual do projeto.
  • Para iOS 17+, a Apple recomenda SwiftUI como framework principal; o UIKit permanece para interfaces personalizadas complexas e suporte de versões antigas.

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.

Discutir o projeto

Leia também