@ViewBuilder

SwiftUI Mid-level Swift 5.4+ iOS 17+ Reviewed By Alok Singh

Pick the fix

func badge() -> some View { if isNew { Text("New") } else { Image(systemName: "star") } } doesn't compile. Best fix?

Options
Hint 1 of 1

Opaque types need one concrete type. What combines branches?

Choose an answer, then open Show answer below to check it.

Show answer

Answer: A Mark the function @ViewBuilder

Correct. The builder combines both branches into one concrete type.

Why not the others?
  • B Wrap both branches in AnyView. It compiles, but it erases types for no reason.
  • C Return EmptyView() in the else branch. The branches would still have different types.
  • D Change the return type to any View. any View isn't a View that SwiftUI can render here.

30-second answer

@ViewBuilder is a result builder that turns several view expressions, if/else and switch into one view type. body already uses it. Add it to your own functions, computed properties or closure parameters when they need to return different views in different branches, instead of erasing them with AnyView.

Practise saying it · 30 s. No recording, just a timer

Explain @ViewBuilder.

Say your answer out loud, then check which of these points you covered:

  • Result builder for views
  • Combines branches into one type
  • Avoids AnyView

Deep dive

Builder functions can't contain arbitrary statements like return in each branch.

Take @ViewBuilder content: () -> Content to build container views.

if/else in a builder creates _ConditionalContent, which keeps both types and their identity.

There is a limit on how many statements fit; group large bodies into subviews.

Common mistakes

  • Returning AnyView from helpers.
  • Writing return in some branches of a builder.
  • Huge builder functions instead of subviews.

Senior take & follow-ups

Seniors connect @ViewBuilder to type information and identity, and keep AnyView out.

Follow-up questions

Think of your answer first, then open the hint.

  1. How do you write a container view?

    Show hint

    A generic Content: View with a @ViewBuilder init parameter.

  2. Why does if/else in a builder matter for identity?

    Show hint

    Each branch is a different identity.

Suggest a fix if something here is wrong or out of date.