Die body-Eigenschaft ist das zentrale Element des View-Protokolls in SwiftUI und bestimmt, welcher Inhalt auf dem Bildschirm angezeigt wird. Laut Apple Developer Documentation, 2024 ist body die einzige zwingende Anforderung des View-Protokolls und gibt einen Typ zurück, der demselben Protokoll entspricht. SwiftUI ruft body bei jeder Zustandsänderung auf, um einen neuen Elementbaum zu erstellen und zu vergleichen.
Wichtige Punkte
body ist eine berechnete Eigenschaft, die die einzige zwingende Anforderung des View-Protokolls ist. Jede Struktur, die View entspricht, muss body implementieren. Die Eigenschaft gibt den Inhalt zurück, den SwiftUI auf dem Bildschirm anzeigt — das kann Text, ein Bild, ein Button, ein Container mit verschachtelten Elementen oder jeder andere Typ sein, der dem View-Protokoll entspricht.
Die Signatur von body ist immer festgelegt: var body: some View { get }. Der Rückgabetyp ist some View (ein undurchsichtiger Typ), kein konkreter Typ. Das bedeutet, dass verschiedene Views unterschiedliche konkrete Typen in body zurückgeben können, aber der Swift-Compiler legt den konkreten Typ für jede Implementierung zur Kompilierzeit fest.
Laut WWDC 2022 ist body der Einstiegspunkt für die deklarative Beschreibung der Benutzeroberfläche. Im Gegensatz zu UIKit, wo Sie UIView imperativ erstellen und konfigurieren, beschreiben Sie in SwiftUI deklarativ, was angezeigt werden soll, und SwiftUI berechnet selbst, wie es implementiert wird.
body sollte sich wie eine reine Funktion verhalten — bei gleichen Eingaben (Eigenschaften der Struktur und Zustand) sollte er denselben View-Baum zurückgeben. Wenn body von externem veränderlichem Zustand abhängt (globalen Variablen, UserDefaults ohne den @AppStorage-Wrapper), wird das Verhalten unvorhersehbar und SwiftUI kann den Bildschirm falsch neu zeichnen.
Die berechnete Eigenschaft body speichert keinen Wert — sie wird jedes Mal bei Zugriff berechnet. Wenn SwiftUI feststellt, dass sich der Zustand geändert hat, erstellt es die View-Struktur neu und liest den neuen Wert von body, um den aktuellen Elementbaum für die Anzeige zu erhalten.
struct CounterView: View {
@State private var count = 0
var body: some View {
VStack {
Text("Zähler: \(count)")
.font(.largeTitle)
Button("Erhöhen") {
count += 1
}
.padding()
.background(.blue)
.foregroundColor(.white)
.cornerRadius(8)
}
}
}
In diesem Beispiel gibt body einen VStack zurück, der einen Text und einen Button mit Modifikatoren enthält. Wenn der Button gedrückt wird, wird die @State-Eigenschaft count erhöht, SwiftUI erstellt die CounterView-Struktur neu und ruft body erneut auf, um den aktualisierten Baum mit dem neuen Textwert zu erhalten.
Modifikatoren (.font, .padding, .background, .foregroundColor, .cornerRadius) ändern die ursprüngliche View nicht, sondern umschließen sie mit ModifiedContent — einem neuen Typ, der die Modifikation hinzufügt. Jeder Modifikator erstellt eine weitere Verschachtelungsebene, was für die Leistung wichtig zu beachten ist.
some View im Rückgabetyp von body ist nicht nur eine Konvention, sondern eine Compiler-Anforderung. Swift verlangt, dass alle Rückgabepfade in body denselben konkreten Typ haben. Ohne @ViewBuilder können Sie nicht in einem Zweig Text und in einem anderen Button zurückgeben — der Compiler gibt einen Fehler aus.
struct ConditionalView: View {
var isReady: Bool
@ViewBuilder
var body: some View {
if isReady {
Text("Bereit")
.foregroundColor(.green)
} else {
ProgressView()
}
}
}
@ViewBuilder auf body ermöglicht die Verwendung von bedingter Logik (if/else, switch) ohne Compiler-Fehler. ViewBuilder umschließt automatisch verschiedene Zweige mit ConditionalContent — einem speziellen Typ, der Unterschiede konkreter Typen verbirgt. Dies ist eine Schlüsselfunktion für die Erstellung dynamischer Oberflächen.
Ohne @ViewBuilder versucht der Compiler, einen einzigen Typ für alle Rückgabepfade abzuleiten. Wenn die Typen unterschiedlich sind — tritt ein Fehler auf. Deshalb wendet SwiftUI implizit @ViewBuilder auf body in View-Deklarationen an, obwohl Sie im Benutzercode die Annotation explizit für benutzerdefinierte Methoden und Eigenschaften hinzufügen müssen, die mehrere Views zurückgeben.
Die Verwendung von some View anstelle eines konkreten Typs verringert die Leistung nicht — der Compiler kennt den genauen Typ zur Kompilierzeit und generiert direkten Code ohne dynamische Dispatch. AnyView hingegen verwendet Typ-Auslöschung (Type Erasure) mit dem Overhead der Umhüllung in einem existenziellen Container.
body wird von SwiftUI in drei Hauptszenarien aufgerufen: wenn die View zum ersten Mal angezeigt wird, wenn sich @State/@Binding/@ObservedObject/@StateObject ändert, und wenn die Eltern-View neue Werte über den Initialisierer übergibt. SwiftUI kann body auch aufrufen, wenn sich Umgebungswerte (@Environment) ändern.
Die Häufigkeit der body-Aufrufe sollte Sie nicht beunruhigen — SwiftUI optimiert das Neuzeichnen durch den Identitäts-Mechanismus. Jede View in der Hierarchie hat eine eindeutige Kennung. Wenn sich Identität und Eingabedaten nicht geändert haben — wird body nicht aufgerufen, selbst wenn die Eltern-View neu gezeichnet wird. Dies wird durch Equatable-Vergleich und strukturelle Stabilität erreicht.
struct ParentView: View {
var body: some View {
ChildView(name: "Alice") // Stabile Identität
}
}
struct ChildView: View {
let name: String
var body: some View {
Text("Hallo, \(name)!")
}
}
In diesem Beispiel: Wenn ParentView neu gezeichnet wird, aber denselben name-Wert übergibt — wird ChildView.body nicht aufgerufen. SwiftUI vergleicht die Eingabedaten der Struktur und überspringt, falls unverändert, das Neuzeichnen der Kindkomponente. Dies ist der View-Differenzierungs-Mechanismus.
Es gibt mehrere Fallstricke, die zu unerwarteten body-Aufrufen führen: Verwendung von Klassen ohne ObservableObject, Übergabe von Closures, die innerhalb von body erstellt wurden (jede Closure-Erstellung ergibt eine neue Identität), und falsche Verwendung von EquatableView. Wenn body zu häufig aufgerufen wird — überprüfen Sie die Identitätsstabilität aller Kindkomponenten.
Erste Regel: body sollte minimal sein. Verlagern Sie komplexe Logik in separate berechnete Eigenschaften oder Methoden, die View zurückgeben. Dies verbessert die Lesbarkeit und ermöglicht SwiftUI, genauer zu bestimmen, welche Teile der Hierarchie sich geändert haben. Teilen Sie große bodies in Unterkomponenten mit klaren Verantwortungsbereichen auf.
Zweite Regel: Verwenden Sie body nicht zum Ausführen von Arbeit. Daten laden, Netzwerkoperationen, Datenbankschreibvorgänge — all dies sollte außerhalb von body in Aufgaben (tasks), onChange-Modifikatoren oder über ObservableObject erfolgen. body ist ausschließlich für die Deklaration der Benutzeroberfläche bestimmt.
Dritte Regel: Verwenden Sie die EquatableView-Eigenschaft oder ein benutzerdefiniertes Equatable-Protokoll für Views, wenn der standardmäßige Strukturvergleich nicht ausreicht. Damit können Sie SwiftUI explizit mitteilen, wann eine Kind-View neu gezeichnet werden muss, und unnötige body-Aufrufe vermeiden.
Vierte Regel: Wenn body komplexe Berechnungen enthält (Formatierung, Filterung, Sortierung) — verwenden Sie @State zum Caching des Ergebnisses oder verlagern Sie Berechnungen in eine separate Methode, die von onChange aufgerufen wird. Wiederholte Berechnungen in body bei jeder Zustandsaktualisierung sind eine häufige Ursache für Animationsverzögerungen.
Fünfte Regel: Stellen Sie für Listen (List, ForEach) stabile Identifikatoren über den id-Parameter sicher. Ohne stabile Identität erstellt ForEach bei jeder Änderung alle Elemente neu und ruft body für jedes auf, selbst wenn sich nur ein Element geändert hat.
Häufig gestellte Fragen
body ist die berechnete Eigenschaft des View-Protokolls, die den anzuzeigenden Inhalt zurückgibt. Es ist die einzige zwingende Anforderung des Protokolls. Der Rückgabetyp ist some View, was SwiftUI ermöglicht, die Hierarchie zur Kompilierzeit zu optimieren.
Ja, SwiftUI ruft body bei jeder Zustandsänderung (@State, @Binding, @ObservedObject) oder bei Änderung der Eingabedaten auf. Dies ist normales Verhalten für ein deklaratives Framework. SwiftUI optimiert die Aufruffrequenz durch den Identitätsmechanismus und Equatable-Vergleich.
some View ist ein undurchsichtiger Typ, der die konkrete Implementierung verbirgt. Der Compiler legt den Typ zur Kompilierzeit fest und gewährleistet so direkte Aufrufleistung. Dies bietet Flexibilität: Sie können den Rückgabetyp ändern, ohne die Signatur zu ändern.
Nein, body kann nicht optional sein — der Rückgabetyp some View erlaubt nil nicht. Wenn Sie ein Element bedingt ausblenden müssen, verwenden Sie bedingte Logik innerhalb von @ViewBuilder oder geben Sie EmptyView zurück, das in der Hierarchie keinen Platz einnimmt.
Jeder Modifikator erstellt eine neue ModifiedContent-Schicht und erhöht die Hierarchietiefe. Für die meisten Bildschirme (bis zu 50 Modifikatoren) ist der Einfluss vernachlässigbar. Eine übermäßige Anzahl von Modifikatoren (Hunderte) kann das Diffing verlangsamen. Gruppieren Sie verwandte Modifikatoren in benutzerdefinierten Erweiterungen.
Zusammenfassung
Wir entwickeln eine mobile Applikation schlüsselfertig
IT Sectr entwickelt seit 2017 iOS- und Android-Apps für Startups und Unternehmen. Wir beraten Sie und schlagen die beste Lösung vor.
Lesen Sie auch