SwiftUI & Layout API. Extra trailing closure passed in call

Hello

I'm trying to compose a layout using the Layout API.

I have already written the code for both the Layout Stack I want to use and the view I am using it in, however I am getting an "Extra trailing closure passed in call" error in the view I am using the Stack in.

Here is the code:

import SwiftUI
struct StairsView: View {
    var body: some View {
        Group{
            MyStairsStack{
                Text("Hello, World!")
                
                Text("Hello, World!")
                
                Text("Hello, World!")
            }
        }
    }
}

struct MyStairsStack: Layout{
    func sizeThatFits(proposal: ProposedViewSize, subviews: Subviews, cache: inout Void) -> CGSize {
        return .init(width: proposal.width ?? 0, height: proposal.height ?? 0)
    }
    
    func placeSubviews(in bounds: CGRect, proposal: ProposedViewSize, subviews: Subviews, cache: inout Void) {
        guard !subviews.isEmpty else { return }
        
        let viewSize = maxSize(subViews: subviews)
        
        var origin = bounds.origin
        let maxWidth = bounds.width
        
        subviews.forEach { view in
            if (origin.x + (viewSize.width + 10) >= maxWidth){
                origin.x = bounds.origin.x
            }
            
            view.place(at: origin, proposal: proposal)
            origin.x += (viewSize.width + 10)
            origin.y += (viewSize.height + 10)
        }
    }
    
    private func maxSize(subViews: Subviews) -> CGSize{
        subViews.map { $0.sizeThatFits(.unspecified) }.reduce(.zero) { currentMax, subviewSize in
            CGSize(
                width: max(currentMax.width, subviewSize.width),
                height: max(currentMax.height, subviewSize.height))
        }
    }
}

The error is at line 5

Thank You for your time

Answered by BabyJ in 717999022

The method behind the trailing closure accepts a closure as a parameter that can only return a single view.

func callAsFunction<V>(_ content: () -> V) -> some View where V : View

Since its not marked with @ViewBuilder, like most of the other SwiftUI view closures, you can only return one view.

So your view will have to be declared like this if you want multiple views:

MyStairsStack() {
    Group {
        Text("Hello, World!")
        Text("Hello, World!")
        Text("Hello, World!")
    }
}

You need to add parentheses before you add the trailing closure, like this:

MyStairsStack() {
  ...
}

Read through the documentation and it tells you how to initialise custom Layout instances, easier ways to do it as well as why.

Accepted Answer

The method behind the trailing closure accepts a closure as a parameter that can only return a single view.

func callAsFunction<V>(_ content: () -> V) -> some View where V : View

Since its not marked with @ViewBuilder, like most of the other SwiftUI view closures, you can only return one view.

So your view will have to be declared like this if you want multiple views:

MyStairsStack() {
    Group {
        Text("Hello, World!")
        Text("Hello, World!")
        Text("Hello, World!")
    }
}
SwiftUI &amp; Layout API. Extra trailing closure passed in call
 
 
Q