Returning multiple View objects from a closure in Swift

Viewed 571

I often see code like this:

VStack {
  Text("A")
  Text("B")
}

From looking at the swift tutorials, I know that this is shorthand for specifying a closure as the last parameter to a function. However, afaik if the return keyword is not specified, a closure will implicitly return the result of the expression inside.

In this case, there are two Text objects. Are they returned as a tuple or a list? I know it works, but its unclear to me, what exactly is being returned from the closure.

3 Answers

The initial ability to omit the return statement was introduced in Swift Evolution 255 - This change only allowed for a single return value. In fact, the ability to return multiple values was considered in this proposal and discarded.

The structure you are asking about was originally introduced by Apple as a private implementation to support SwiftUI but has now been officially adopted in Swift Evolution 289 - Function Builders.

By referring to the introduction section of that document you can see that the values are, indeed, returned as a tuple.

// Original source code:
@TupleBuilder
func build() -> (Int, Int, Int) {
  1
  2
  3
}

// This code is interpreted exactly as if it were this code:
func build() -> (Int, Int, Int) {
  let _a = TupleBuilder.buildExpression(1)
  let _b = TupleBuilder.buildExpression(2)
  let _c = TupleBuilder.buildExpression(3)
  return TupleBuilder.buildBlock(_a, _b, _c)
}

When we see this code:

VStack {
  Text("A")
  Text("B")
}

It is unclear what would be returned, unless we use VStack, then SwiftUI knows what we want, the code could be like this:

HStack {
  Text("A")
  Text("B")
}

Here also is unclear what we want, unless we say to SwiftUI that we want HStack, But if you use like this:

CustomView {
  Text("A")
  Text("B")
}

SwiftUI return it as VStack the inside content always! Also in all those cases that I said, Swift works with @ViewBuilder to make that happen. and they are tuple.

ViewBuilder Apple

Related