Function builder attribute 'ViewBuilder' can only be applied to a property if it defines a getter

Swift SwiftUI
26 February 2021

This is a quick follow up on the last two entries, as I've received multiple feedbacks around this error.

New in Swift 5.4/Xcode 12.5, @resultBuilder has gained support for stored properties.

This makes it possible to associate @ViewBuilder, SwiftUI's @resultBuilder for building views, to view properties:

struct FSView<Content: View>: View {
  // 👇🏻 new in Swift 5.4
  @ViewBuilder let content: Content

  var body: some View {
    ...
  }
}

As this declaration requires Swift 5.4, trying to build it with Xcode 12.4/Swift 5.3 or earlier will trigger a Function builder attribute 'ViewBuilder' can only be applied to a property if it defines a getter build error.

Function builder, a.k.a. @_functionBuilder, was the former name of @resultBuilder, which has been renamed on the latest Swift evolution proposal.

If we'd like to build this code with previous versions of Xcode/Swift, we need to remove the property @ViewBuilder association, and declare a new initializer with a @ViewBuilder parameter instead:

// Before Swift 5.4
struct FSView<Content: View>: View {
  // 👇🏻 We can't add @ViewBuilder in stored properties before Swift 5.4
  let content: Content

  // 👇🏻 Explicit init with @ViewBuilder parameter
  init(@ViewBuilder content: () -> Content) {
    self.content = content()
  }

  var body: some View {
    ...
  }
}

Beside the different declaration, the views will look and behave exactly the same.

In other words, from Xcode 12.5, Swift 5.4 will automatically synthesize this initializer, allowing us to write even more compact views.

Hope this clear things up! Thank you for reading and please let me know if you have any other question :)

⭑⭑⭑⭑⭑

Related articles

More Swift articles

Browse all

More SwiftUI articles

Browse all