SwiftUI:两个具有相同宽度/高度的按钮

Eve*_*vel 4 user-interface swift swiftui

我的 H/VStack 中有 2 个按钮。它们都包含一些文本,在我的示例中为“播放”和“暂停”。我希望两个按钮具有相同的宽度(和高度),由最大的按钮决定。我在这里找到了一些答案,但不幸的是我无法让这段代码工作。

下面的代码说明了这个问题:

import SwiftUI

struct ButtonsView: View {
    var body: some View {
        VStack {
            Button(action: { print("PLAY tapped") }){
                Text("Play")
            }

            Button(action: { print("PAUSE tapped") }) {
                Text("Pause")
            }
        }
    }
}

struct ButtonsView_Previews: PreviewProvider {
    static var previews: some View {
        ButtonsView()
    }
}
Run Code Online (Sandbox Code Playgroud)

Xcode 的 tvOS 预览显示了问题:

在此输入图像描述

我将感谢对新手的解释

Asp*_*eri 5

这是基于运行时的方法,无需硬编码。这个想法是在绘制过程中检测可用按钮的最大宽度,并将其应用于下一个更新周期的其他按钮(无论如何,它对用户来说是流畅且不可见的)。

使用 Xcode 11.4 / tvOS 13.4 进行测试

必需:用于测试的模拟器或设备,因为使用了运行时调度的更新

演示

struct ButtonsView: View {
    @State private var maxWidth: CGFloat = .zero
    var body: some View {
        VStack {
            Button(action: { print("PLAY tapped") }){
                Text("Play")
                    .background(rectReader($maxWidth))
                    .frame(minWidth: maxWidth)
            }.id(maxWidth) // !! to rebuild button (tvOS specific)

            Button(action: { print("PAUSE tapped") }) {
                Text("Pause Long Demo")
                    .background(rectReader($maxWidth))
                    .frame(minWidth: maxWidth)
            }.id(maxWidth) // !! to rebuild button (tvOS specific)
        }
    }

    // helper reader of view intrinsic width
    private func rectReader(_ binding: Binding<CGFloat>) -> some View {
        return GeometryReader { gp -> Color in
            DispatchQueue.main.async {
                binding.wrappedValue = max(binding.wrappedValue, gp.frame(in: .local).width)
            }
            return Color.clear
        }
    }

}
Run Code Online (Sandbox Code Playgroud)