📦ViewBuilder

SwiftUIViews

You typically use ViewBuilder as a parameter attribute for child view-producing closure parameters, allowing those closures to provide multiple child views. 👉 SwiftUI ⟩ ViewViewBuilder

As for ViewBuilders, it is mainly used to create custom container views, which can also become a reusable view component. 👉 Understanding SwiftUI's ViewModifiers and ViewBuilders

A good rule of thumb for me has to be to use a modifier first, and only use a builder when the code patterns really pulled strongly for that syntax. 👉 View Builders - NetSplit.com

@ViewBuilder is one of the possible function builders. 👉 Swift with Majid

ViewBuilder as a Parameter

  • You typically use ViewBuilder as a parameter attribute for child view-producing closure parameters, allowing those closures to provide multiple child views.

  • 通常 @ViewBuilder closure 具有 @escaping 的特性,因為一般這個 closure 會在 .init(content:) 中傳進來,然後在 var body 中用到,如果沒有事先設為 @escaping 的話,那麼這個 closure 在 .init 中傳進來後,會隨著 .init 結束而消失,因此也沒辦法事後在 var body 中用到,所以會產生 compiler 錯誤。 問:那麼 @escaping closure 會存放在那裏呢 🤔❓ 答:通常會存放在函數外部的變數或陣列中。

  • 但反過來說,如果傳進來的 @ViewBuilder closure 馬上在 .init 中就用掉了,這時就不需要加 @escaping 這個屬性了。

Using ViewBuilder ⭐️

共有四個步驟:

// ⭐️ Step 1: Create a View struct like this:
// ⭐️ Note  : `Content` conforms to `View`
struct MyContainerView<Content: View>: View {
    ...
}

Examples

// ⭐️ generic structure
struct Card<Content> : View where Content : View {
    
    // ⭐️ 卡片的內容,由 .init(content:) 傳進來。
    // ⭐️ `Content` 的型別也是由 init(content:) 決定。
    var content: Content
    
    // init(content:)
    init(@ViewBuilder content: () -> Content) {  // ⭐️ @ViewBuilder 
        self.content = content()
    }
    
    // view body
    var body: some View {
        // 卡片內容
        content
            // 卡片風格
            .padding()                  // 留白邊
            .foregroundColor(.black)    
            .background(Color.white)    // 白背景
            .cornerRadius(8)            // 截圓角
            .shadow(radius: 4)          // 畫陰影
    }
}

Last updated

Was this helpful?