------------------------- | Custom Container View | |-----------------------| | [ Child View 1 ] | | [ Child View 2 ] | | [ Child View 3 ] | | | -------------------------
ViewBuilder for custom containers in iOS Swift - Mini App: Build & Ship
import SwiftUI struct CustomContainer<Content: View>: View { let content: Content init(@ViewBuilder content: () -> Content) { self.content = content() } var body: some View { // TODO: Arrange child views vertically with spacing, padding, background, and corner radius } } struct ContentView: View { var body: some View { CustomContainer { Text("Child View 1") Text("Child View 2") Text("Child View 3") } } } struct ContentView_Previews: PreviewProvider { static var previews: some View { ContentView() } }
import SwiftUI struct CustomContainer<Content: View>: View { let content: Content init(@ViewBuilder content: () -> Content) { self.content = content() } var body: some View { VStack(spacing: 10) { content } .padding(20) .background(Color(white: 0.9)) .cornerRadius(10) } } struct ContentView: View { var body: some View { CustomContainer { Text("Child View 1") Text("Child View 2") Text("Child View 3") } .padding() // Add some outer padding for better layout } } struct ContentView_Previews: PreviewProvider { static var previews: some View { ContentView() } }
We created a generic CustomContainer struct that accepts multiple child views using the @ViewBuilder attribute in its initializer. This allows us to pass several views inside the container easily.
Inside the body, we use a VStack with spacing 10 to arrange the child views vertically with space between them. We add padding of 20 points around the stack to give some breathing room.
The background color is set to a light gray using Color(white: 0.9), and corners are rounded with a radius of 10 points to make the container visually distinct.
Finally, in ContentView, we use CustomContainer to display three text views labeled "Child View 1", "Child View 2", and "Child View 3".
------------------------- | Custom Container View | |-----------------------| | Child View 1 | | | | Child View 2 | | | | Child View 3 | | | -------------------------
Practice
@ViewBuilder in SwiftUI custom containers?Solution
Step 1: Understand what
@ViewBuilderdoes@ViewBuilderlets you write multiple views inside a closure without needing to wrap them in a container likeVStack.Step 2: Identify the purpose in custom containers
It simplifies building flexible UI containers that can hold many child views easily.Final Answer:
To allow multiple child views inside a closure without extra wrappers -> Option CQuick Check:
@ViewBuilder= multiple child views [OK]
- Thinking it handles animations
- Confusing it with data storage
- Assuming it manages network calls
@ViewBuilder in SwiftUI?Solution
Step 1: Check the correct syntax for
The parameter must be a closure returning@ViewBuilderparametersome Viewand marked with@ViewBuilder.Step 2: Verify the return type and usage
The function returnssome Viewand calls the closure withcontent().Final Answer:
func MyContainer(@ViewBuilder content: () -> some View) -> some View { content() } -> Option AQuick Check:
Correct syntax = func MyContainer(@ViewBuilder content: () -> some View) -> some View { content() } [OK]
- Using View instead of some View
- Missing @ViewBuilder attribute
- Wrong return type in function
struct MyStack: View {
let content: () -> some View
var body: some View {
VStack {
content()
}
}
}
struct ContentView: View {
var body: some View {
MyStack {
Text("Hello")
Text("World")
}
}
}Solution
Step 1: Analyze the content closure type
The content closure returnssome Viewbut is not marked with@ViewBuilder, so it cannot return multiple views.Step 2: Understand the effect on multiple child views
Passing twoTextviews without@ViewBuildercauses a compile-time error because the closure expects a single view.Final Answer:
A compile-time error because multiple views are not allowed -> Option BQuick Check:
Missing @ViewBuilder causes error with multiple views [OK]
- Assuming multiple views work without @ViewBuilder
- Thinking texts concatenate automatically
- Ignoring closure return type rules
struct CustomContainer: View {
let content: () -> some View
var body: some View {
HStack {
content()
}
}
}
// Usage
CustomContainer {
Text("One")
Text("Two")
}Solution
Step 1: Check the content closure declaration
The content closure is declared as() -> some Viewwithout@ViewBuilder, so it cannot accept multiple views.Step 2: Fix by adding
Adding@ViewBuilder@ViewBuilderbefore the content parameter allows multiple child views inside the closure.Final Answer:
Missing @ViewBuilder on content parameter; add @ViewBuilder to fix -> Option DQuick Check:
Use @ViewBuilder to accept multiple views [OK]
- Changing container type instead of fixing closure
- Misunderstanding closure return types
- Trying to convert struct to function unnecessarily
@ViewBuilder to achieve this?Solution
Step 1: Use generic Content type with @ViewBuilder
To accept multiple views, declare a genericContent: Viewand mark theinitparameter with@ViewBuilder.Step 2: Build the body with VStack and add border
WrapcontentinsideVStackand apply.border(Color.red)modifier to the stack.Final Answer:
struct RedBorderStack<Content: View>: View { let content: Content init(@ViewBuilder content: () -> Content) { self.content = content() } var body: some View { VStack { content } .border(Color.red) } } -> Option AQuick Check:
Generic + @ViewBuilder in init + VStack { content } + border [OK]
- Omitting generic Content type
- Not using @ViewBuilder for multiple views
- Placing border on content() instead of VStack
Ready to prove it?
Pass the test and this pattern moves unknown
