Avoid Init with ViewBuilder

51 views Asked by At

In my SwiftUI project, I have a view that includes some ViewBuilder code:

struct MyView<Content: View>: View {
    var tag: Int
    var label: String
    var image: String
    var disableReset: Bool
    var content: () -> Content

    init(
        tag: Int, label: String, image: String, disableReset: Bool = false,
        @ViewBuilder _ content: @escaping () -> Content
    ) {
        self.tag = tag
        self.label = label
        self.image = image
        self.disableReset = disableReset
        self.content = content
    } //init
    
    var body: some View {
        //does some stuff with content()
    } //body
} //MyView

And this might be called like:

MyView(tag: 1, label: "Chapter", image: "book") {
    ContentView()
} 

Is there a cleaner way to write MyView so that it avoids the lengthy, redundant init() function? Usually I don't need an init() in my SwiftUI views, but is init() necessary here because I'm using a ViewBuilder variable? This is purely a stylistic question, it just annoys me to see this OOP-like form in my SwiftUI view.

2

There are 2 answers

0
protasm On BEST ANSWER

Thanks to @lorem-ipsum for the solution:

struct MyView<Content: View>: View {
    var tag: Int
    var label: String
    var image: String
    var disableReset: Bool = false //add default value to property
    @ViewBuilder var content: () -> Content //add @ViewBuilder to property

    //no init() needed
    
    var body: some View {
        //does some stuff with content()
    } //body
} //MyView
0
malhal On

Generally this is a bad idea and you should stick to body as your only view builder but you can fix it with:

self.content = content()

This is necessary to allow View's dependency tracking to keep working.