SwiftUI: struct View vs @ViewBuilder

Viewed 1106

If I want to render a list of item in SwiftUI, I could do something like this (using XCode 12):

struct MyView: View {
    let texts: [String]
    var body: some View {
        ScrollView {
            LazyVStack {
                ForEach(texts.indices, id: \.self) { index in
                    MyRow(label: texts[index])
                }
            }
        }
    }

    struct MyRow: View {
        let label: String
        var body: some View {
            Text(label).font(.title3).padding()
        }
    }
}

Instead of being a struct, MyRow can be a function, which makes the code a bit more concise and functional:

struct MyView: View {
    let texts: [String]
    var body: some View {
        ScrollView {
            LazyVStack {
                ForEach(texts.indices, id: \.self) { index in
                    MyRow(label: texts[index])
                }
            }
        }
    }

    @ViewBuilder func MyRow(label: String) -> some View {
        Text(label).font(.title3).padding()
    }
}

I'd like to understand the difference between the two approaches. Are there cases where you would prefer one over the other?

The first thing that comes to mind is that you cannot have @State properties with functions, which means that you need to use the struct approach if your view needs state.

Is that all? Are there cases where one approach is better in terms of optimisation? Debugging? Features? Portability?

1 Answers

@ViewBuilder is mostly used to conditionally render views without using parsers like AnyView(YourView). To quote Apple Developer's website: "Clients of this function can use multiple-statement closures to provide several child views". For example, if you want to show a view depending on a variable, i.e. rendering View1 if a certain variable is true and View2 if it is false.

Related