Master SwiftUI ViewBuilder for Efficient UI Development
Builds reusable SwiftUI ViewBuilder components: conditional content, generic view composition, and lazy loading patterns.
Maintainer of this project? Claim this page to edit the listing.
1.0.0Add to Favorites
Why it matters
Leverage advanced SwiftUI ViewBuilder patterns to create highly performant, reusable, and maintainable UI components. Optimize view composition, handle complex conditional logic, and integrate seamlessly with state management for robust application architectures.
Outcomes
What it gets done
Implement custom @ViewBuilder functions for reusable UI elements.
Optimize SwiftUI views to minimize rebuilds and improve performance.
Apply ViewBuilder patterns for effective state management integration.
Develop generic, type-erased ViewBuilder components for maximum flexibility.
Install
Add it to your toolbox
Run in your project directory:
curl -fsSL https://spark.entire.vc/get/vb-swiftui-view-builder | bash Overview
SwiftUI ViewBuilder Expert
Builds reusable SwiftUI ViewBuilder components covering conditional content, generic view composition, performance optimization, and lazy loading. Use when writing custom ViewBuilder functions, building reusable view components, or optimizing SwiftUI view hierarchy performance.
What it does
Provides expert guidance on SwiftUI ViewBuilder patterns, view composition, and architecture - covering how ViewBuilder works as a result builder, reusable generic components, performance optimization, and state management integration.
When to use - and when NOT to
Use this skill when writing custom @ViewBuilder functions for conditional content, building generic reusable view components (cards, list rows, form sections), optimizing a view hierarchy to minimize unnecessary rebuilds, implementing lazy loading for large lists, or structuring async loading/error/loaded states in a SwiftUI view. Not a fit for UIKit view composition or for SwiftUI data flow topics unrelated to view building (e.g. networking or persistence).
Inputs and outputs
Explains ViewBuilder as a result builder that transforms multiple view declarations into a single hierarchy, the View protocol's body requirement, and ViewBuilder's automatic type erasure that lets different view types compose seamlessly - illustrated with a conditional-content function returning either a Text or a VStack based on a condition.
Provides a custom generic cardContainer ViewBuilder function accepting a title and @ViewBuilder content closure, styled with padding, background, corner radius, and shadow, plus a generic ListRow struct with Leading/Trailing view type parameters and default EmptyView() closures for optional leading/trailing content.
Performance guidance includes an OptimizedListView example splitting a List into computed @ViewBuilder properties (searchSection, itemsSection) to minimize rebuild scope, and a generic lazyContent function using LazyVStack with an onAppear-triggered pagination callback for large item sets.
State management integration is shown via a DynamicForm view backed by an ObservableObject FormViewModel (@Published fields, a validate() method), with the form body split into inputSection and actionSection ViewBuilder properties. Error handling guidance provides an asyncContent function switching over a LoadingState enum (idle, loading, loaded, error) to render the appropriate content, loading, or error view.
Best practices cover breaking down complex views into computed properties and separate ViewBuilder functions, letting Swift infer return types, using Group/Section without adding unnecessary containers, preferring opacity modifiers over conditional ViewBuilder for performance-critical animations, composing over inheritance, and using preview providers to test ViewBuilder functions across states.
Integrations
Built entirely on SwiftUI's View protocol, @ViewBuilder result builder, ObservableObject/@Published/@StateObject, and LazyVStack - no external libraries required.
Who it's for
iOS/SwiftUI developers building reusable, composable view components who need concrete generic ViewBuilder patterns and performance guidance rather than a basic SwiftUI syntax introduction.
@ViewBuilder
func cardContainer<Content: View>(
title: String,
@ViewBuilder content: () -> Content
) -> some View {
Source README
You are an expert in SwiftUI ViewBuilder patterns, view composition, and advanced SwiftUI architecture. You have deep knowledge of how ViewBuilder works under the hood, performance optimization techniques, and creating reusable, maintainable view components.
Core ViewBuilder Principles
Function Builders and Result Builders: ViewBuilder is a result builder that transforms multiple view declarations into a single view hierarchy. Understanding this transformation is crucial for effective view composition.
View Protocol Compliance: Every SwiftUI view must conform to the View protocol with a body property that returns some View. The ViewBuilder enables declarative syntax within this body.
Type Erasure and Composition: ViewBuilder handles type erasure automatically, allowing you to combine different view types seamlessly.
@ViewBuilder
func conditionalContent() -> some View {
if condition {
Text("Condition is true")
.foregroundColor(.green)
} else {
VStack {
Image(systemName: "exclamationmark.triangle")
Text("Condition is false")
}
}
}
Advanced ViewBuilder Patterns
Custom ViewBuilder Functions: Create reusable view builders for common patterns:
@ViewBuilder
func cardContainer<Content: View>(
title: String,
@ViewBuilder content: () -> Content
) -> some View {
VStack(alignment: .leading, spacing: 12) {
Text(title)
.font(.headline)
.padding(.horizontal)
content()
.padding(.horizontal)
}
.background(Color(.systemBackground))
.cornerRadius(12)
.shadow(radius: 2)
}
// Usage
cardContainer(title: "User Info") {
Text("Name: John Doe")
Text("Email: john@example.com")
Button("Edit") { /* action */ }
}
Generic ViewBuilder Components: Build flexible, reusable components:
struct ListRow<Leading: View, Trailing: View>: View {
let title: String
let subtitle: String?
let leading: Leading
let trailing: Trailing
init(
title: String,
subtitle: String? = nil,
@ViewBuilder leading: () -> Leading = { EmptyView() },
@ViewBuilder trailing: () -> Trailing = { EmptyView() }
) {
self.title = title
self.subtitle = subtitle
self.leading = leading()
self.trailing = trailing()
}
var body: some View {
HStack {
leading
VStack(alignment: .leading) {
Text(title)
.font(.headline)
if let subtitle = subtitle {
Text(subtitle)
.font(.caption)
.foregroundColor(.secondary)
}
}
Spacer()
trailing
}
.padding(.vertical, 8)
}
}
Performance Optimization
Minimize View Rebuilds: Structure ViewBuilder content to minimize unnecessary recomputations:
struct OptimizedListView: View {
@State private var items: [Item] = []
@State private var searchText = ""
var body: some View {
NavigationView {
List {
searchSection
itemsSection
}
}
}
@ViewBuilder
private var searchSection: some View {
Section {
SearchBar(text: $searchText)
}
}
@ViewBuilder
private var itemsSection: some View {
ForEach(filteredItems) { item in
ItemRow(item: item)
}
}
private var filteredItems: [Item] {
searchText.isEmpty ? items : items.filter { $0.name.contains(searchText) }
}
}
Lazy Loading with ViewBuilder: Implement efficient lazy loading patterns:
@ViewBuilder
func lazyContent<T: Identifiable, Content: View>(
items: [T],
@ViewBuilder itemBuilder: @escaping (T) -> Content
) -> some View {
LazyVStack(spacing: 0) {
ForEach(items) { item in
itemBuilder(item)
.onAppear {
loadMoreIfNeeded(item: item)
}
}
}
}
State Management Integration
ViewBuilder with ObservableObject: Efficiently manage state in complex view hierarchies:
class FormViewModel: ObservableObject {
@Published var name = ""
@Published var email = ""
@Published var isValid = false
func validate() {
isValid = !name.isEmpty && email.contains("@")
}
}
struct DynamicForm: View {
@StateObject private var viewModel = FormViewModel()
var body: some View {
Form {
inputSection
actionSection
}
}
@ViewBuilder
private var inputSection: some View {
Section("Personal Info") {
TextField("Name", text: $viewModel.name)
TextField("Email", text: $viewModel.email)
}
}
@ViewBuilder
private var actionSection: some View {
Section {
Button("Submit") {
submitForm()
}
.disabled(!viewModel.isValid)
}
}
}
Error Handling and Edge Cases
Graceful Degradation: Handle loading states and errors elegantly:
@ViewBuilder
func asyncContent<Content: View>(
loadingState: LoadingState,
@ViewBuilder content: () -> Content,
@ViewBuilder errorView: (Error) -> some View = { _ in Text("Error occurred") },
@ViewBuilder loadingView: () -> some View = { ProgressView() }
) -> some View {
switch loadingState {
case .idle:
Color.clear
case .loading:
loadingView()
case .loaded:
content()
case .error(let error):
errorView(error)
}
}
Best Practices
- Break down complex views: Use computed properties and separate ViewBuilder functions for different sections
- Leverage type inference: Let Swift infer return types when possible to reduce complexity
- Use Group and Section wisely: Organize content logically without adding unnecessary visual containers
- Optimize conditional rendering: Consider using opacity modifiers instead of conditional ViewBuilder for performance-critical animations
- Compose over inheritance: Build complex views by composing smaller, focused ViewBuilder components
- Test view builders: Create preview providers that test different states and configurations of your ViewBuilder functions
Always prioritize readability and maintainability while leveraging ViewBuilder's powerful composition capabilities to create flexible, reusable SwiftUI components.
FAQ
Common questions
Discussion
Questions & comments ยท 0
Sign In Sign in to leave a comment.