@ViewBuilder: bu nədir, SwiftUI-də View üçün result builder

Müəllif: IT Sectr Dərc olunub: 2026-06-24 Oxuma vaxtı: 7 dəq

@ViewBuilder — SwiftUI-də View iyerarxiyasının deklarativ qurulması üçün nəzərdə tutulmuş result builder annotasiyasıdır. Apple Developer Documentation, 2024-ə əsasən, @ViewBuilder çoxsaylı ifadələr və şərti məntiqi olan kod blokunu Swift kompilyatoru üçün anlaşılan vahid View tipinə çevirir. Bu annotasiya olmadan SwiftUI-nin if/else və body-də çoxsaylı elementləri olan tanış deklarativ sintaksisindən istifadə etmək mümkün olmazdı.

Əsas məqamlar

  • @ViewBuilder — bir neçə View-i lazımsız konteynerlər olmadan kompozisiyada birləşdirən result builder
  • buildBlock — ifadələr ardıcıllığını 10 elementədək TupleView-ə bükür
  • buildEither — if/else və switch budaqları üçün ConditionalContent yaradır
  • Məhdudiyyət — Group və ya ForEach olmadan bir blokda 10 elementədək
  • Qeyri-aşkar tətbiq — body artıq @ViewBuilder-ə bükülüb, istifadəçi funksiyaları aşkar annotasiya tələb edir

SwiftUI-də @ViewBuilder nədir?

@ViewBuilder — result builder (SE-0289) nümunəsini həyata keçirən annotasiyadır və SwiftUI-yə deklarativ sintaksis vasitəsilə bir neçə View-i bir kompozisiyada toplamağa imkan verir. O, çoxsaylı ifadələri, şərti konstruksiyaları və opsional dəyərləri müvafiq tiplərə avtomatik bükür: TupleView, ConditionalContent, OptionalContent.

Result builder meydana çıxmazdan əvvəl proqramçılar elementləri əl ilə VStack və ya HStack-ə bükməli, şərti məntiq üçün üçlü operatorlar və ya fabrik metodlarından istifadə etməli idilər. @ViewBuilder SwiftUI sintaksisini yığcam və oxunaqlı etdi, if/else və dövrləri olan adi Swift kimi görünən kod yazmağa imkan verdi.

Swift Evolution SE-0289-a əsasən, result builders SwiftUI-yə bağlı olmayan ümumi mexanizmdir. @ViewBuilder bu mexanizmin implementasiyalarından biridir, sətirlər qurmaq üçün @StringBuilder və digər DSL-lər üçün kitabxana implementasiyaları ilə yanaşı. SwiftUI-də @ViewBuilder təkcə body üçün deyil, həm də konteyner parametrləri-zamkaniyaları üçün istifadə olunur (VStack, HStack, ZStack, List).

İmperativ yanaşmadan fərqi

İmperativ UIKit-də siz UIView yaradır, onun xassələrini konfiqurasiya edir və addSubview vasitəsilə iyerarxiyaya əlavə edirsiniz. @ViewBuilder ilə SwiftUI-də siz deklarativ şəkildə hansı View-lərin göstəriləcəyini təsvir edirsiniz və SwiftUI özü dövlət dəyişiklikləri əsasında elementlərin yaradılması, yenilənməsi və silinməsini idarə edir.

@ViewBuilder necə işləyir: result builder

Result builder — ifadələr ardıcıllığını buildBlock, buildOptional, buildEither və digər statik metodlar vasitəsilə bir mürəkkəb dəyərə çevirən Swift mexanizmidir. Kompilyator @ViewBuilder annotasiyasını gördükdə, bu metodları avtomatik olaraq kod blokuna tətbiq edir.

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 1-dən 10-dək ifadə qəbul edir və TupleView qaytarır. Hər arlıq (ifadə sayı) buildBlock-in öz overloaduna malikdir: buildBlock<C0>-dan buildBlock<C0, C1, ..., C9>-dək. Məhz buna görə bir @ViewBuilder blokunda elementlərin sayı 10 ilə məhdudlaşır.

buildEither (first/second) if/else konstruksiyalarını emal edir. Hər budaq müvafiq metoda ötürülür və nəticə ConditionalContent-ə bükülür — budaqların konkret tiplərini gizlədən və SwiftUI üçün vahid interfeys təmin edən tip.

@ViewBuilder-in qeyri-aşkar işi

SwiftUI-də body xassəsi artıq @ViewBuilder ilə qeyri-aşkar annotasiya olunub — siz bu annotasiyanı kodda görmürsünüz, amma kompilyator onu avtomatik tətbiq edir. Lakin bir neçə View qaytaran istifadəçi xassələri və ya zamkaniyə parametrləri üçün annotasiyanı aşkar şəkildə göstərmək lazımdır.

@ViewBuilder məhdudiyyətləri və onları necə keçmək olar

Məhdudiyyət 1 — blokda 10 element. Bu @ViewBuilder-in ən məşhur məhdudiyyətidir. Bir səviyyədə 10-dan çox element göstərmək lazımdırsa, kompilyator xəta verir. Bunu Group, ForEach, List və ya altkomponentlərə bölməklə keçmək olar. Group vizual iç-içəlik əlavə etmir, lakin hər Group bir element sayılır.

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")
        }
    }
}

Məhdudiyyət 2 — bəzi konstruksiyaların dəstəklənməməsi. @ViewBuilder do/catch, guard, for-in (ForEach olmadan) və digər idarəetmə konstruksiyalarını dəstəkləmir. Dövrlər üçün ForEach-dən identifikasiya edilə bilən məlumatlarla istifadə edin. Xəta emalı üçün Result və ya opsional dəyərlər qəbul edən ayrıca View-lərdən istifadə edin.

Məhdudiyyət 3 — debug çətinliyi. @ViewBuilder-də xətalarda kompilyator kök səbəbi tapmaq çətin olan uzun mesajlar verir. Tipik problemlər: if/else budaqlarında tip uyğunsuzluğu, 10 element limitinin aşılması və ya tələb olunan buildBlock overloadunun olmaması.

@ViewBuilder istifadə nümunələri

Nümunə 1: if/else ilə şərti göstərmə. @ViewBuilder-in ən çox yayılmış istifadə ssenarisi. Üçlü operatorlar və ya fabrik metodları olmadan vəziyyətdən asılı olaraq müxtəlif View-lər göstərməyə imkan verir.

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)
        }
    }
}

Nümunə 2: funksiya və init parametrlərində @ViewBuilder. Zamkaniyə vasitəsilə uşaq View-lər qəbul edən təkrar istifadə olunan konteynerlər yaratmaq üçün istifadə olunur. Bu kitabxana və UI komponentləri üçün standart nümunədir.

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)
    }
}

Nümunə 3: ForEach ilə kompozisiya. @ViewBuilder ForEach ilə düzgün işləyərək məlumat massivindən elementlərin dinamik generasiyasını təmin edir. Hər ForEach elementi @ViewBuilder kontekstində bir ifadə sayılır.

Təkrar istifadə olunan komponentlər üçün xüsusi ViewBuilder yaratmaq

Xüsusi ViewBuilder — @ViewBuilder ilə annotasiya olunmuş, some View qaytaran istifadəçi funksiyası və ya xassəsidir. Belə funksiyalar mürəkkəb göstərmə məntiqini kapsullaşdırmağa və onu tətbiqin müxtəlif hissələrində təkrar istifadə etməyə imkan verir.

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
        }
    }
}

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

FormRow(label: "Gender") {
    Picker("Select", selection: $gender) {
        Text("Kişi").tag(Gender.male)
        Text("Qadın").tag(Gender.female)
    }
}

Vacib qayda: @ViewBuilder ilə xüsusi funksiya some View qaytarmalıdır, konkret tip və ya View protokolu yox. Yalnız opaque tip konkret implementasiyanı gizlətməyə və kompozisiya elastikliyini qorumağa imkan verir.

Performans: xüsusi @ViewBuilder funksiyaları body-də birbaşa kodla müqayisədə əlavə yük yaratmır. Kompilyator çağırışları inline edir və nəticə kodu optimallaşdırır. Body-ni @ViewBuilder funksiyalarına bölmək performans itkisi olmadan oxunaqlılığı artırır.

Tez-tez verilən suallar

SwiftUI-də @ViewBuilder nədir?

@ViewBuilder — çoxsaylı ifadələri və şərtləri olan kod blokunu vahid View tipinə çevirən result builder annotasiyasıdır. SwiftUI-nin deklarativ interfeysi daxilində tanış Swift sintaksisindən (if/else, switch, opsional ifadələr) istifadə etməyə imkan verir.

Niyə @ViewBuilder-da 10-dan çox element yerləşdirmək olmur?

Məhdudiyyət buildBlock implementasiyası ilə bağlıdır — hər arlıq üçün (1-dən 10-dək) metodun ayrıca overloadu mövcuddur. Swift variadic generics-i dəstəkləmir, buna görə overloadların sayı sabitdir. Bunu keçmək üçün Group, ForEach və ya altkomponentlərdən istifadə edin.

Body-dən əvvəl @ViewBuilder-i aşkar göstərmək lazımdır?

Xeyr, View protokolu qeyri-aşkar @ViewBuilder-i body xassəsinə tətbiq edir. Lakin bir neçə View qaytaran istifadəçi xassələri, metodları və zamkaniyə parametrləri üçün annotasiyanı aşkar göstərmək lazımdır. Əks halda kompilyator çoxsaylı ifadələri emal edə bilməyəcək.

@ViewBuilder opsional ifadələri necə emal edir?

Opsional ifadələr üçün buildIf metodu istifadə olunur, o opsional View qəbul edir və dəyər varsa onu qaytarır. Dəyər nil-dirsə — buildIf nil qaytarır və element göstərilmir. Bu, body-də if let istifadəsinə imkan verir.

@ViewBuilder switch ilə istifadə oluna bilərmi?

Bəli, Swift 5.9-dan etibarən @ViewBuilder switch-i buildExpression metodu vasitəsilə dəstəkləyir. Kompilyator hər case budağını müvafiq buildEither çağırışına çevirir. Switch dəstəyi iç-içə if/else konstruksiyaları ilə müqayisədə kodu daha oxunaqlı edir.

Nəticə

  • @ViewBuilder — SwiftUI-də View iyerarxiyasının deklarativ qurulması üçün result builder
  • buildBlock ifadələr ardıcıllığını TupleView-ə bükür (10 elementədək)
  • buildEither if/else və switch budaqları üçün ConditionalContent yaradır
  • buildIf opsional ifadələri və if-siz else-i emal edir
  • Group və ForEach blokda 10 element məhdudiyyətini keçməyə kömək edir
  • Xüsusi @ViewBuilder funksiyaları performans itkisi olmadan təkrar istifadəni yaxşılaşdırır
  • @ViewBuilder body-ə qeyri-aşkar tətbiq olunur, lakin parametrlər üçün aşkar annotasiya tələb edir

Açar təslim mobil tətbiq hazırlayacağıq

IT Sectr 2017-ci ildən startaplar və bizneslər üçün iOS və Android tətbiqləri yaradır. Sizə məsləhət verəcəyik və ən yaxşı həlli təklif edəcəyik.

Layihəni müzakirə et

Həm də oxuyun