View Protocol é o protocolo fundamental do SwiftUI ao qual qualquer componente visual de interface deve estar em conformidade. De acordo com Apple Developer Documentation, 2024, View define um único contrato: uma estrutura ou classe que implementa este protocolo deve fornecer uma propriedade computada body. Através deste protocolo, o SwiftUI constrói toda a hierarquia de telas, desde simples rótulos de texto até estruturas de navegação complexas.
Pontos principais
View Protocol é o protocolo central do SwiftUI que define como qualquer elemento visual descreve seu conteúdo. Ao contrário do UIKit, onde cada elemento herda de UIView através de classes, o SwiftUI usa uma abordagem orientada a protocolos: qualquer tipo que esteja em conformidade com o protocolo View pode ser exibido na tela.
O protocolo View requer a implementação de uma única propriedade computada body que retorna algum conteúdo. No entanto, por trás dessa simplicidade há um poderoso sistema de composição: body pode retornar qualquer tipo que esteja em conformidade com View, incluindo primitivas (Text, Image, Button), contêineres (VStack, HStack, ZStack) e componentes compostos personalizados.
De acordo com a WWDC 2023, mais de 95% de todas as telas em aplicativos SwiftUI são construídas através da composição de estruturas que implementam o protocolo View. Isso torna o View Protocol o fundamento de toda a arquitetura SwiftUI.
O SwiftUI exige que View seja um value type (struct), não uma classe. Esta é uma decisão arquitetônica chave: os value types têm um ciclo de vida previsível, não possuem estado mutável compartilhado e permitem que o SwiftUI determine eficientemente quais partes da hierarquia mudaram e precisam ser redesenhadas.
Se você tentar fazer View ser uma classe, o compilador emitirá um erro: o protocolo View herda do protocolo DynamicViewProperty, que requer value semantics. As classes podem estar em conformidade com View, mas isso quebra a abordagem idiomática e perde os benefícios das atualizações automáticas.
body é o único requisito obrigatório do protocolo View. É uma propriedade computada que retorna o conteúdo exibido na tela. O tipo de retorno é some View, que significa “um tipo que está em conformidade com View, a ser determinado pelo compilador”.
struct GreetingView: View {
var name: String
var body: some View {
VStack {
Text("Hello, \(name)!")
.font(.title)
.foregroundColor(.blue)
Button("Start") {
print("Button pressed")
}
}
}
}
Como body funciona: O SwiftUI chama body toda vez que o estado do aplicativo muda e é necessário redesenhar. O framework compara a nova árvore de Views com a antiga e aplica apenas as alterações necessárias (diffing). Esta é uma abordagem totalmente declarativa — você descreve o que deve ser exibido, e o SwiftUI cuida de como implementar.
Um detalhe importante: body não deve ter efeitos colaterais. Ele é chamado várias vezes durante a vida do aplicativo, e se body modificar o estado externo — isso leva a um comportamento imprevisível. Para efeitos colaterais, use task, onChange ou DispatchQueue.
O SwiftUI impõe uma restrição: body pode retornar apenas um único elemento raiz. Se você precisar exibir vários elementos no mesmo nível, envolva-os em um contêiner — VStack, HStack, ZStack ou Group. Com a introdução do @ViewBuilder, essa limitação se tornou menos perceptível, mas conceitualmente body sempre retorna um único View.
some View é a sintaxe de tipo opaco (opaque type) introduzida no Swift 5.1 especificamente para o SwiftUI. Significa que uma função ou propriedade retorna um tipo concreto que está em conformidade com o protocolo View, mas o código chamador não sabe e não precisa saber qual tipo exato é retornado.
O compilador Swift fixa o tipo concreto em tempo de compilação para cada implementação de body, mas o oculta do mundo exterior. Isso permite que o SwiftUI otimize a hierarquia de Views conhecendo os tipos exatos de todos os componentes, ao mesmo tempo que dá ao desenvolvedor flexibilidade para alterar a implementação sem modificar a assinatura.
struct ContentView: View {
var body: some View {
Text("Hello, World!") // Compiler knows this is Text
}
}
Por que some View e não apenas View? Se body retornasse apenas View (como um protocolo), o SwiftUI não seria capaz de determinar o tipo concreto em tempo de compilação. Isso adicionaria sobrecarga para encapsulamento em um contêiner existencial. some View dá ao compilador informações suficientes para otimização, mantendo a flexibilidade do protocolo.
A principal limitação é que body deve retornar o mesmo tipo. Você não pode retornar Text em um ramo de uma condição e Image em outro sem envoltórios especiais (AnyView, Group ou @ViewBuilder). O compilador verifica isso em tempo de compilação: todos os caminhos de retorno possíveis devem ter o mesmo tipo.
Para contornar essa limitação, usa-se @ViewBuilder (cria um único tipo TupleView), Group (que também retorna um único tipo) ou AnyView (apaga o tipo mas adiciona sobrecarga). AnyView deve ser usado apenas quando outras opções não são possíveis, pois desativa as otimizações do SwiftUI.
@ViewBuilder é um result builder cuja anotação permite montar vários Views em uma única composição sem contêineres aninhados. @ViewBuilder envolve automaticamente múltiplas expressões em uma tupla (TupleView) ou aplica lógica condicional (If / else / switch) com o tipo de retorno correto.
struct DashboardView: View {
var isLoggedIn: Bool
@ViewBuilder
var body: some View {
if isLoggedIn {
Text("Welcome!")
.font(.largeTitle)
ProfileCard()
} else {
LoginButton()
.padding()
}
}
}
Como @ViewBuilder funciona: o compilador transforma cada bloco de código dentro de @ViewBuilder em chamadas aos métodos estáticos buildBlock, buildEither, buildOptional, etc. Se um bloco contém múltiplas expressões — elas são envolvidas em TupleView. Se um bloco contém lógica condicional — o compilador gera ConditionalContent, ocultando o tipo do ramo.
@ViewBuilder impõe uma limitação: até 10 elementos por bloco (limitação do TupleView). Se você precisar montar mais de dez elementos, use Group, ForEach ou divida em subcomponentes. Essa limitação existe porque o Swift gera uma sobrecarga separada de buildBlock para cada aridade de 1 a 10.
Composição é um princípio chave do SwiftUI: interfaces complexas são construídas a partir de componentes View pequenos e reutilizáveis. Cada componente implementa o protocolo View e é responsável por sua parte da tela. Os modificadores (font, padding, foregroundColor) são aplicados a um View e retornam um novo View com configurações alteradas.
Modificadores no SwiftUI não são mutações, mas a criação de um novo envoltório ao redor do View original. Cada modificador retorna um novo tipo (ModifiedContent), permitindo que o SwiftUI construa uma árvore de modificadores e redesenhe eficientemente apenas as partes alteradas. A ordem de aplicação dos modificadores importa: ordens diferentes produzem resultados visuais diferentes.
Text("Hello, SwiftUI!")
.font(.title) // ModifiedContent
.padding() // ModifiedContent<..., PaddingModifier>
.background(.yellow) // ModifiedContent<..., BackgroundModifier>
.cornerRadius(8) // ModifiedContent<..., CornerRadiusModifier>
Otimização de desempenho: O SwiftUI não compara os valores concretos de View, mas sua identidade através do mecanismo de identidade (id, ForEach, identidade estável das estruturas). Se a estrutura do View não mudou — body não é chamado. Isso é alcançado através da comparação Equatable e do mecanismo PreferenceKey para passar dados para cima na hierarquia.
Para uma composição eficaz, recomenda-se dividir telas complexas em subcomponentes independentes, cada um com seu estado mínimo. Isso permite que o SwiftUI redesenhe apenas as partes alteradas da hierarquia, não a tela inteira.
Perguntas frequentes
View Protocol é o protocolo base do SwiftUI ao qual qualquer componente exibido deve estar em conformidade. Ele requer uma única propriedade computada body que retorna conteúdo. Todos os elementos padrão do SwiftUI — Text, Button, Image, VStack — implementam este protocolo.
O SwiftUI usa value semantics para atualizações previsíveis da interface. As estruturas não têm estado mutável compartilhado, permitindo que o SwiftUI compare eficientemente a hierarquia de Views antiga e nova e redesenhe apenas os elementos alterados. As classes quebram essa otimização.
body retorna some View — um tipo opaco que oculta a implementação concreta. Na verdade, retorna qualquer tipo que esteja em conformidade com View: Text, Image, VStack, estruturas personalizadas. O compilador fixa o tipo concreto em tempo de compilação para otimização.
some View é um tipo opaco com o tipo concreto fixado em tempo de compilação. AnyView é um apagamento de tipo (type erasure) que envolve qualquer View em um único contêiner. some View é mais eficiente; AnyView adiciona sobrecarga e é usado apenas quando é necessária uma troca dinâmica de tipo.
Até 10 elementos — esta é a limitação do TupleView, que gera buildBlock para aridades de 1 a 10. Se você precisar de mais elementos, use Group, ForEach, List ou divida em subcomponentes. Esta limitação existe no nível do compilador Swift.
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