


@ViewBuilder 프로토콜 준수 클로저init(title: String, @ViewBuilder content: () -> Content) {
        self.title = title
        self.content = content()
    }
...
HeaderViewGeneric(title: "CONTENT CLOSURE!") {
                    HStack {
                        Text("HI!")
                        Image(systemName: "bolt.fill")
                    }
                }
@ViewBuilder 프로토콜을 준수하는 클로저 매개변수는 곧 해당 뷰에서 어떻게 뷰 컨텐츠를 그릴지 알려주는 방법. 뷰 구조체 이니셜라이저 단에서 클로저 자체를 매핑struct HeaderViewRegular: View {
    let title: String
    let description: String?
    let iconName: String?
    var body: some View {
        VStack(alignment: .leading) {
            Text(title)
                .font(.largeTitle)
                .fontWeight(.semibold)
            if let description = description {
                Text(description)
                    .font(.callout)
            }
            if let iconName = iconName {
                Image(systemName: iconName)
                    .resizable()
                    .scaledToFit()
                    .frame(width: 20, height: 20)
            }
            RoundedRectangle(cornerRadius: 5)
                .frame(height: 2)
        }
        .frame(maxWidth: .infinity, alignment: .leading)
        .padding()
    }
}
description, iconName 등)struct HeaderViewGeneric<Content:View>: View {
    let title: String
    let content: Content
    
    init(title: String, content: Content) {
        self.title = title
        self.content = content
    }
    
    init(title: String, @ViewBuilder content: () -> Content) {
        self.title = title
        self.content = content()
    }
    var body: some View {
        VStack(alignment: .leading) {
            Text(title)
                .font(.largeTitle)
                .fontWeight(.semibold)
            content
            RoundedRectangle(cornerRadius: 5)
                .frame(height: 2)
        }
        .frame(maxWidth: .infinity, alignment: .leading)
        .padding()
    }
}
struct ViewBuilderBootCamp: View {
    var body: some View {
        ScrollView {
            VStack {
                HeaderViewRegular(title: "NEW TITLE", description: "HELLO", iconName: "flame.fill")
                HeaderViewRegular(title: "Another TITLE", description: nil, iconName: nil)
                HeaderViewGeneric(title: "GENERIC TITLE", content: Text("CONTENT!"))
                HeaderViewGeneric(title: "GENERIC TITLE", content: Image(systemName: "flame.fill"))
                HeaderViewGeneric(title: "GENERIC TITLE", content: HStack {
                    Text("HELLO!")
                    Image(systemName: "flame.fill")
                })
                HeaderViewGeneric(title: "CONTENT CLOSURE!") {
                    HStack {
                        Text("HI!")
                        Image(systemName: "bolt.fill")
                    }
                }
                HeaderViewGeneric(title: "CUSTOM HSTACK") {
                    CustomHStack {
                        Text("HELLO!")
                        Text("THIS IS CUSTOM HSTACK!")
                    }
                }
                Spacer()
            }
        }
    }
}
struct CustomHStack<Content: View>:View {
    let content: Content
    
    init(@ViewBuilder content: () -> Content) {
        self.content = content()
    }
    
    var body: some View {
        HStack {
            content
        }
    }
}
@ViewBuilder 프로토콜을 준수하는 클로저여야 함struct LocalViewBuilder: View {
    enum ViewType {
        case one, two, three
    }
    @State private var type: ViewType = ViewType.one
    var body: some View {
        VStack {
            buttonView
            .padding()
            headerSection
        }
    }
    
    @ViewBuilder private var headerSection: some View {
        switch type {
        case .one:
            viewOne
        case .two:
            viewTwo
        case .three:
            viewThree
        }
    }
    
    private var buttonView: some View {
        HStack {
            Button {
                type = .one
            } label: {
                Text("TYPE ONE")
                    .withDefaultButtonFormmating()
            }
            .withPressableStyle(0.9)
            Button {
                type = .two
            } label: {
                Text("TYPE TWO")
                    .withDefaultButtonFormmating()
            }
            .withPressableStyle(0.9)
            Button {
                type = .three
            } label: {
                Text("TYPE ONE")
                    .withDefaultButtonFormmating()
            }
            .withPressableStyle(0.9)
        }
        .padding()
    }
    
    private var viewOne: some View {
        Text("ONE")
    }
    
    private var viewTwo: some View {
        VStack {
            Text("TWO")
            Image(systemName: "flame.fill")
        }
    }
    
    private var viewThree: some View {
        HStack {
            Text("THREE")
            Image(systemName: "flame.fill")
        }
    }
}
@ViewBuilder 주의switch case를 통해 보다 효율적으로 작성 가능
VStack, HStack 등)를 호출하는 형태