@ViewBuilder: nedir, SwiftUI'de View için result builder

Yazar: IT Sectr Yayınlanma: 2026-06-24 Okuma süresi: 7 dk

@ViewBuilder, SwiftUI'de View hiyerarşilerinin bildirimsel oluşturumu için tasarlanmış bir result builder ek açıklamasıdır. Apple Developer Documentation, 2024'e göre, @ViewBuilder birden çok ifade ve koşullu mantık içeren bir kod bloğunu Swift derleyicisinin anlayabileceği tek bir View türüne dönüştürür. Bu ek açıklama olmadan, if/else ve body içinde birden çok öğeyle tanıdık bildirimsel SwiftUI sözdizimini kullanmak imkansız olurdu.

Önemli Noktalar

  • @ViewBuilder — birden çok View'i ekstra kapsayıcı olmadan bir kompozisyonda birleştiren result builder
  • buildBlock — ifade dizisini 10 öğeye kadar TupleView içinde sarar
  • buildEither — if/else ve switch dalları için ConditionalContent oluşturur
  • Sınırlama — Group veya ForEach olmadan tek bir blokta 10 öğeye kadar
  • Örtük uygulama — body zaten @ViewBuilder içinde sarılıdır, özel işlevler açık ek açıklama gerektirir

SwiftUI'de @ViewBuilder nedir?

@ViewBuilder, result builder desenini (SE-0289) uygulayan ve SwiftUI'nin bildirimsel sözdizimi kullanarak birden çok View'i tek bir kompozisyonda birleştirmesine olanak tanıyan bir ek açıklamadır. Birden çok ifadeyi, koşullu yapıları ve isteğe bağlı değerleri otomatik olarak ilgili türlerine sarar: TupleView, ConditionalContent, OptionalContent.

Result builder'lar ortaya çıkmadan önce, geliştiricilerin öğeleri manuel olarak VStack veya HStack içinde sarması ve koşullu mantık için üçlü operatörler veya fabrika yöntemleri kullanması gerekiyordu. @ViewBuilder, SwiftUI sözdizimini kısa ve okunabilir hale getirerek if/else ve döngülerle normal Swift gibi görünen kod yazmayı mümkün kıldı.

Swift Evolution SE-0289'a göre, result builder'lar SwiftUI'ye bağlı olmayan genel bir mekanizmadır. @ViewBuilder, bu mekanizmanın bir uygulamasıdır; ayrıca @StringBuilder (dizi oluşturma) ve diğer DSL'ler için kitaplık uygulamaları da vardır. SwiftUI'de @ViewBuilder yalnızca body için değil, aynı zamanda kapsayıcıların (VStack, HStack, ZStack, List) closure parametreleri için de kullanılır.

Emir kipi yaklaşımından farkı

Emir kipi UIKit'te, açıkça bir UIView oluşturur, özelliklerini yapılandırır ve addSubview aracılığıyla hiyerarşiye eklersiniz. @ViewBuilder ile SwiftUI'de, hangi View'lerin görüntüleneceğini bildirimsel olarak tanımlarsınız ve SwiftUI, durum değişikliklerine göre öğelerin oluşturulmasını, güncellenmesini ve kaldırılmasını yönetir.

@ViewBuilder nasıl çalışır: result builder

Result builder, static yöntemler buildBlock, buildOptional, buildEither ve diğerleri aracılığıyla bir ifade dizisini tek bir bileşik değere dönüştüren bir Swift mekanizmasıdır. Derleyici @ViewBuilder ek açıklamasını gördüğünde, derleme sırasında bu yöntemleri otomatik olarak kod bloğuna uygular.

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 ila 10 ifadeyi kabul eder ve bir TupleView döndürür. Her arite (ifade sayısı) kendi buildBlock aşırı yüklemesine sahiptir: buildBlock'dan buildBlock'a kadar. Bu nedenle tek bir @ViewBuilder bloğundaki öğe sayısı 10 ile sınırlıdır.

buildEither (first/second) if/else yapılarını işler. Her dal ilgili yönteme iletilir ve sonuç ConditionalContent içinde sarılır — bu, belirli dal türlerini gizleyen ve SwiftUI için birleşik bir arayüz sağlayan bir türdür.

@ViewBuilder'ın örtük davranışı

SwiftUI'de, body özelliği zaten örtük olarak @ViewBuilder ile ek açıklamalıdır — bu ek açıklamayı kodda görmezsiniz, ancak derleyici onu otomatik olarak uygular. Ancak, birden çok View döndüren özel özellikler veya closure parametreleri için ek açıklamanın açıkça belirtilmesi gerekir.

@ViewBuilder sınırlamaları ve bunlardan nasıl kaçınılır

Sınırlama 1 — bir blokta 10 öğe. Bu, @ViewBuilder'ın en bilinen sınırlamasıdır. Aynı seviyede 10'dan fazla öğe görüntülemeniz gerekiyorsa, derleyici bir hata verecektir. Çözümler arasında Group, ForEach, List veya alt bileşenlere ayırma bulunur. Group görsel iç içe eklemez, ancak her Group bir öğe olarak 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")
        }
    }
}

Sınırlama 2 — bazı yapılar için destek eksikliği. @ViewBuilder do/catch, guard, for-in (ForEach olmadan) ve diğer kontrol akışı yapılarını desteklemez. Döngüler için, tanımlanabilir verilerle ForEach kullanın. Hata işleme için, Result veya isteğe bağlı değerler kabul eden ayrı View'ler kullanın.

Sınırlama 3 — hata ayıklama karmaşıklığı. @ViewBuilder'da hatalar oluştuğunda, derleyici, temel nedeni bulmanın zor olduğu ayrıntılı mesajlar üretir. Tipik sorunlar: if/else dallarında tür uyuşmazlığı, 10 öğe sınırının aşılması veya gerekli buildBlock aşırı yüklemelerinin olmaması.

@ViewBuilder kullanım desenleri

Desen 1: if/else ile koşullu görüntüleme. @ViewBuilder'ın en yaygın kullanım durumu. Üçlü operatörler veya fabrika yöntemleri kullanmadan duruma bağlı olarak farklı View'ler göstermeye olanak tanır.

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

Desen 2: işlev ve başlatıcı parametrelerinde @ViewBuilder. Bir closure aracılığıyla alt View'leri kabul eden yeniden kullanılabilir kapsayıcılar oluşturmak için kullanılır. Bu, kitaplıklar ve UI bileşenleri için standart desendir.

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

Desen 3: ForEach ile kompozisyon. @ViewBuilder, ForEach ile doğru şekilde çalışarak bir veri dizisinden öğelerin dinamik olarak oluşturulmasına olanak tanır. ForEach'in her öğesi, @ViewBuilder bağlamında bir ifade olarak sayılır.

Yeniden kullanılabilir bileşenler için özel ViewBuilder oluşturma

Özel ViewBuilder, @ViewBuilder ile ek açıklamalı ve some View döndüren kullanıcı tanımlı bir işlev veya özelliktir. Bu tür işlevler, karmaşık görüntüleme mantığını kapsüllemeye ve uygulamanın farklı bölümlerinde yeniden kullanmaya olanak tanır.

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

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

FormRow(label: "Gender") {
    Picker("Select", selection: $gender) {
        Text("Erkek").tag(Gender.male)
        Text("Kadın").tag(Gender.female)
    }
}

Önemli kural: @ViewBuilder ile özel bir işlev, somut bir tür veya View protokolü değil, some View döndürmelidir. Yalnızca opak tür, kompozisyon esnekliğini korurken somut uygulamayı gizlemeye olanak tanır.

Performans: özel @ViewBuilder işlevleri, doğrudan body koduna kıyasla ek yük eklemez. Derleyici çağrıları satır içi yapar ve sonuç kodunu optimize eder. Body'yi @ViewBuilder işlevlerine bölmek, performanstan ödün vermeden okunabilirliği artırır.

Sıkça Sorulan Sorular

SwiftUI'de @ViewBuilder nedir?

@ViewBuilder, birden çok ifade ve koşul içeren bir kod bloğunu tek bir View türüne dönüştüren bir result builder ek açıklamasıdır. SwiftUI'nin bildirimsel UI'sı içinde tanıdık Swift sözdizimini (if/else, switch, isteğe bağlı ifadeler) kullanmaya olanak tanır.

@ViewBuilder'a neden 10'dan fazla öğe konulamaz?

Sınırlama, buildBlock uygulamasından kaynaklanır — 1'den 10'a kadar her arite için yöntemin ayrı bir aşırı yüklemesi vardır. Swift değişken jenerikleri desteklemez, bu nedenle aşırı yükleme sayısı sabittir. Bunu aşmak için Group, ForEach veya alt bileşenler kullanın.

Body'den önce @ViewBuilder'ı açıkça belirtmeli miyim?

Hayır, View protokolü body özelliğine @ViewBuilder'ı örtük olarak uygular. Ancak, birden çok View döndüren özel özellikler, yöntemler ve closure parametreleri için ek açıklamanın açıkça belirtilmesi gerekir. Aksi takdirde derleyici birden çok ifadeyi işleyemez.

@ViewBuilder isteğe bağlı ifadeleri nasıl işler?

İsteğe bağlı ifadeler için, isteğe bağlı bir View kabul eden ve bir değer varsa onu döndüren buildIf yöntemi kullanılır. Değer nil ise, buildIf nil döndürür ve öğe görüntülenmez. Bu, body içinde if let kullanmaya olanak tanır.

@ViewBuilder switch ile kullanılabilir mi?

Evet, Swift 5.9'dan itibaren @ViewBuilder, buildExpression yöntemi aracılığıyla switch'i destekler. Derleyici her case dalını ilgili buildEither çağrısına dönüştürür. Switch desteği, iç içe if/else yapılarına kıyasla kodu daha okunabilir hale getirir.

Özet

  • @ViewBuilder — SwiftUI'de bildirimsel View hiyerarşisi oluşturmak için result builder
  • buildBlock ifade dizisini TupleView içinde sarar (10 öğeye kadar)
  • buildEither if/else ve switch dalları için ConditionalContent oluşturur
  • buildIf isteğe bağlı ifadeleri ve else'siz if'i işler
  • Group ve ForEach, blok başına 10 öğe sınırını aşmaya yardımcı olur
  • Özel @ViewBuilder işlevleri, performans kaybı olmadan yeniden kullanılabilirliği artırır
  • @ViewBuilder body'ye örtük olarak uygulanır, ancak parametreler için açık ek açıklama gerektirir

Anahtar teslim bir mobil uygulama geliştireceğiz

IT Sectr, 2017'den beri girişimler ve işletmeler için iOS ve Android uygulamaları oluşturmaktadır. Size danışmanlık yapacak ve en iyi çözümü önereceğiz.

Projeyi tartış

Ayrıca okuyun