@ViewBuilder: ce este, result builder pentru View în SwiftUI

Autor: IT Sectr Publicat: 2026-06-24 Timp de citire: 7 min

@ViewBuilder — este o adnotare result builder în SwiftUI, destinată construirii declarative a ierarhiei View. Conform Apple Developer Documentation, 2024, @ViewBuilder transformă un bloc de cod cu multiple expresii și logică condițională într-un singur tip View, înțeles de compilatorul Swift. Fără această adnotare, ar fi imposibil să folosești sintaxa declarativă familiară SwiftUI cu if/else și mai multe elemente în corpul body.

Principalele

  • @ViewBuilder — result builder care combină mai multe View într-o compoziție fără containere inutile
  • buildBlock — înfășoară o secvență de expresii în TupleView până la 10 elemente
  • buildEither — creează ConditionalContent pentru ramurile if/else și switch
  • Limitare — până la 10 elemente într-un bloc fără Group sau ForEach
  • Aplicare implicită — body este deja înfășurat în @ViewBuilder, funcțiile utilizatorului necesită adnotare explicită

Ce este @ViewBuilder în SwiftUI?

@ViewBuilder — este o adnotare care implementează pattern-ul result builder (SE-0289), permițând SwiftUI să colecteze mai multe View într-o singură compoziție folosind sintaxa declarativă. Ea înfășoară automat expresii multiple, construcții condiționale și valori opționale în tipuri corespunzătoare: TupleView, ConditionalContent, OptionalContent.

Înainte de apariția result builder, dezvoltatorii trebuiau să înfășoare manual elementele în VStack sau HStack, iar pentru logica condițională să folosească operatori ternari sau metode factory. @ViewBuilder a făcut sintaxa SwiftUI concisă și ușor de citit, permițând scrierea unui cod care arată ca Swift obișnuit cu if/else și bucle.

Conform Swift Evolution SE-0289, result builders sunt un mecanism general, nelegat de SwiftUI. @ViewBuilder este una dintre implementările acestui mecanism, alături de @StringBuilder pentru construirea șirurilor și implementări de bibliotecă pentru alte DSL-uri. În SwiftUI, @ViewBuilder este folosit nu doar pentru body, ci și pentru parametrii de închidere ai containerelor (VStack, HStack, ZStack, List).

Diferența față de abordarea imperativă

În UIKit imperativ, creezi imperativ UIView, configurezi proprietățile sale și îl adaugi la ierarhie prin addSubview. În SwiftUI cu @ViewBuilder, descrii declarativ care View trebuie afișate, iar SwiftUI însuși gestionează crearea, actualizarea și ștergerea elementelor pe baza modificărilor de stare.

Cum funcționează @ViewBuilder: result builder

Result builder — este un mecanism Swift care transformă o secvență de expresii într-o singură valoare compusă prin metode statice buildBlock, buildOptional, buildEither și altele. Când compilatorul vede adnotarea @ViewBuilder, aplică automat aceste metode blocului de cod în procesul de compilare.

swift
@resultBuilder
struct ViewBuilder {
    static func buildBlock<C0, C1>(_ c0: C0, _ c1: C1) -> TupleView<(C0, C1)>
    static func buildIf<C>(_ c: C?) -> C?
    static func buildEither<T, F>(first: T) -> ConditionalContent<T, F>
    static func buildEither<T, F>(second: F) -> ConditionalContent<T, F>
}

buildBlock primește de la 1 la 10 expresii și returnează TupleView. Fiecare aritate (număr de expresii) are propriul său overload buildBlock: de la buildBlock<C0> la buildBlock<C0, C1, ..., C9>. Tocmai de aceea numărul de elemente într-un singur bloc @ViewBuilder este limitat la 10.

buildEither (first/second) procesează construcțiile if/else. Fiecare ramură este transmisă metodei corespunzătoare, iar rezultatul este înfășurat în ConditionalContent — un tip care ascunde tipurile specifice ale ramurilor și oferă o interfață unificată pentru SwiftUI.

Funcționarea implicită @ViewBuilder

În SwiftUI, proprietatea body este deja adnotată implicit cu @ViewBuilder — nu vezi această adnotare în cod, dar compilatorul o aplică automat. Totuși, pentru proprietățile utilizatorului care returnează mai multe View sau pentru parametrii de închidere, adnotarea trebuie specificată explicit.

Limitările @ViewBuilder și cum să le eviți

Limitarea 1 — 10 elemente într-un bloc. Aceasta este cea mai cunoscută limitare a @ViewBuilder. Dacă trebuie să afișezi mai mult de 10 elemente la același nivel, compilatorul va da o eroare. Poți evita acest lucru prin Group, ForEach, List sau împărțirea în subcomponente. Group nu adaugă îmbricare vizuală, dar fiecare Group este considerat un element.

swift
struct ManyElementsView: View {
    var body: some View {
        Group {
            Text("1"); Text("2"); Text("3")
            Text("4"); Text("5"); Text("6")
            Text("7"); Text("8"); Text("9")
        }
        Group {
            Text("10"); Text("11"); Text("12")
        }
    }
}

Limitarea 2 — lipsa suportului pentru unele construcții. @ViewBuilder nu suportă do/catch, guard, for-in (fără ForEach) și alte construcții de control. Pentru bucle, folosește ForEach cu date identificabile. Pentru gestionarea erorilor, folosește View separate care primesc Result sau valori opționale.

Limitarea 3 — dificultatea depanării. La erori în @ViewBuilder, compilatorul generează mesaje verbose în care este greu de găsit cauza principală. Probleme tipice: nepotrivirea tipurilor în ramurile if/else, depășirea limitei de 10 elemente sau lipsa overload-ului buildBlock necesar.

Patternuri de utilizare @ViewBuilder

Pattern 1: afișare condițională prin if/else. Cel mai frecvent scenariu de utilizare @ViewBuilder. Permite afișarea diferitelor View în funcție de stare fără a folosi operatori ternari sau metode factory.

swift
struct StatusView: View {
    var status: LoadStatus

    @ViewBuilder
    var body: some View {
        switch status {
        case .loading:
            ProgressView("Loading...")
        case .loaded(let data):
            DataView(data: data)
        case .error(let message):
            ErrorView(message: message)
        }
    }
}

Pattern 2: @ViewBuilder în parametrii funcțiilor și inițializatorilor. Folosit pentru crearea containerelor reutilizabile care primesc View-uri copil prin închidere. Acesta este un pattern standard pentru biblioteci și componente UI.

swift
struct SectionCard<Content: View>: View {
    let title: String
    @ViewBuilder let content: Content

    var body: some View {
        VStack(alignment: .leading) {
            Text(title).font(.headline)
            content
        }
        .padding()
        .background(Color.gray.opacity(0.1))
        .cornerRadius(12)
    }
}

Pattern 3: compoziție cu ForEach. @ViewBuilder funcționează corect cu ForEach, permițând generarea dinamică a elementelor dintr-un array de date. Fiecare element ForEach este considerat o expresie în contextul @ViewBuilder.

Crearea unui ViewBuilder personalizat pentru componente reutilizabile

ViewBuilder personalizat — este o funcție sau proprietate a utilizatorului adnotată cu @ViewBuilder care returnează some View. Astfel de funcții permit încapsularea logicii complexe de afișare și reutilizarea acesteia în diferite părți ale aplicației.

swift
struct FormRow<Content: View>: View {
    let label: String
    @ViewBuilder let content: Content

    var body: some View {
        HStack {
            Text(label)
                .frame(width: 120, alignment: .trailing)
            content
        }
    }
}

// Utilizare:
FormRow(label: "Name") {
    TextField("Enter name", text: $name)
}

FormRow(label: "Gender") {
    Picker("Select", selection: $gender) {
        Text("Masculin").tag(Gender.male)
        Text("Feminin").tag(Gender.female)
    }
}

Regulă importantă: funcția personalizată cu @ViewBuilder trebuie să returneze some View, nu un tip specific sau protocolul View. Doar tipul opaque permite ascunderea implementării specifice și păstrarea flexibilității compoziției.

Performanță: funcțiile personalizate @ViewBuilder nu adaugă overhead comparativ cu codul direct în body. Compilatorul inlinează apelurile și optimizează codul rezultat. Împărțirea body-ului în funcții @ViewBuilder îmbunătățește lizibilitatea fără pierdere de performanță.

Întrebări frecvente

Ce este @ViewBuilder în SwiftUI?

@ViewBuilder — este o adnotare result builder care transformă un bloc de cod cu multiple expresii și condiții într-un singur tip View. Permite utilizarea sintaxei familiare Swift (if/else, switch, expresii opționale) în interiorul UI-ului declarativ SwiftUI.

De ce nu se pot plasa mai mult de 10 elemente în @ViewBuilder?

Limitarea este legată de implementarea buildBlock — pentru fiecare aritate de la 1 la 10 există un overload separat al metodei. Swift nu suportă variadic generics, deci numărul de overload-uri este fix. Pentru a evita aceasta, folosește Group, ForEach sau subcomponente.

Trebuie să specific explicit @ViewBuilder înainte de body?

Nu, protocolul View aplică implicit @ViewBuilder proprietății body. Totuși, pentru proprietățile utilizatorului, metodele și parametrii de închidere care returnează mai multe View, adnotarea trebuie specificată explicit. Fără ea, compilatorul nu va putea procesa expresii multiple.

Cum procesează @ViewBuilder expresiile opționale?

Pentru expresiile opționale se folosește metoda buildIf, care primește un View opțional și îl returnează dacă valoarea există. Dacă valoarea este nil — metoda buildIf returnează nil, iar elementul nu este afișat. Acest lucru permite utilizarea if let în corpul body.

Se poate folosi @ViewBuilder cu switch?

Da, din Swift 5.9 @ViewBuilder suportă switch prin metoda buildExpression. Compilatorul transformă fiecare ramură case într-un apel buildEither corespunzător. Suportul pentru switch face codul mai lizibil comparativ cu construcțiile if/else imbricate.

Rezumat

  • @ViewBuilder — result builder pentru construirea declarativă a ierarhiei View în SwiftUI
  • buildBlock înfășoară o secvență de expresii în TupleView (până la 10 elemente)
  • buildEither creează ConditionalContent pentru ramurile if/else și switch
  • buildIf procesează expresii opționale și if fără else
  • Group și ForEach ajută la evitarea limitării de 10 elemente pe bloc
  • Funcțiile personalizate @ViewBuilder îmbunătățesc reutilizarea fără pierdere de performanță
  • @ViewBuilder se aplică implicit body-ului, dar necesită adnotare explicită pentru parametri

Vom dezvolta o aplicație mobilă la cheie

IT Sectr creează aplicații iOS și Android pentru startup-uri și afaceri din 2017. Vă vom consilia și vă vom propune cea mai bună soluție.

Discutați proiectul

Citiți și