Equal width subviews in a stack

Lets say I have a view like:


VStack {
            Text("Swift")
                .background(Color.green)
            Text("UI")
                .background(Color.red)
        }


How can I make the two Texts have equal widths? Similar to an equal-width constrain in Auto Layout.

This works:


        GeometryReader {container in
            VStack {
                Text("Swift")
                    .frame(width: container.size.width)
                    .background(Color.green)
                Text("UI")
                    .frame(width: container.size.width)
                    .background(Color.red)
            }
        }


You have to have the .frame lines before the background ones.

        MyEqualWidthHStack {
            Button {
                Task {
                    await update()
                }
            } label: {
                Text("update")
                    .frame(maxWidth: .infinity)
            }
            .border(.yellow)
            
            
            Button {
                Task {
                    await sync()
                }
            } label: {
                Text("sync")
                    .frame(maxWidth: .infinity)
            }
            .border(.yellow)
        }

struct MyEqualWidthHStack: Layout {
    func sizeThatFits(
        proposal: ProposedViewSize,
        subviews: Subviews,
        cache: inout Void
    ) -> CGSize {
        // Return a size.
        guard !subviews.isEmpty else { return .zero }

        let maxSize = maxSize(subviews: subviews)
        let spacing = spacing(subviews: subviews)
        let totalSpacing = spacing.reduce(0) { $0 + $1 }

        return CGSize(
            width: maxSize.width * CGFloat(subviews.count) + totalSpacing,
            height: maxSize.height)
    }

    func placeSubviews(
        in bounds: CGRect,
        proposal: ProposedViewSize,
        subviews: Subviews,
        cache: inout Void
    ) {
        // Place child views.
        guard !subviews.isEmpty else { return }
      
        let maxSize = maxSize(subviews: subviews)
        let spacing = spacing(subviews: subviews)

        let placementProposal = ProposedViewSize(width: maxSize.width, height: maxSize.height)
        var x = bounds.minX + maxSize.width / 2
      
        for index in subviews.indices {
            subviews[index].place(
                at: CGPoint(x: x, y: bounds.midY),
                anchor: .center,
                proposal: placementProposal)
            
            x += maxSize.width + spacing[index]
        }
    }
    
    private func maxSize(subviews: Subviews) -> CGSize {
        let subviewSizes = subviews.map { $0.sizeThatFits(.unspecified) }
        let maxSize: CGSize = subviewSizes.reduce(.zero) { currentMax, subviewSize in
            CGSize(
                width: max(currentMax.width, subviewSize.width),
                height: max(currentMax.height, subviewSize.height))
        }

        return maxSize
    }
    
    private func spacing(subviews: Subviews) -> [CGFloat] {
        subviews.indices.map { index in
            guard index < subviews.count - 1 else { return 0 }
            return subviews[index].spacing.distance(
                to: subviews[index + 1].spacing,
                along: .horizontal)
        }
    }
}

https://developer.apple.com/documentation/swiftui/composing_custom_layouts_with_swiftui

So ******* complicated to align and stretch two views, which would otherwise be easy to implement using UIStackView or AutoLayout.

Equal width subviews in a stack
 
 
Q