SwiftUI - 堆栈中的多个对齐指南

Sto*_*one 6 alignment vertical-alignment swiftui

有没有办法在 SwiftUI 堆栈视图 ( HStack/ VStack) 中指定多个对齐参考线?

我确实有如下基本视图设置

HStack {
    VStack { ... }
    VStack { ... }
    VStack { ... }
    VStack { ... }
    VStack { ... }
}
Run Code Online (Sandbox Code Playgroud)

在这里面VStack我确实有不同字体大小的文本。

在此输入图像描述

正如您在屏幕截图中看到的,我能够Text对齐VStack. 我使用基本.alignmentGuide功能做到了这一点。

然而,系统似乎对整体应用“偏移” VStack,而不仅仅是视图Text

是否有可能:

  • 将“对齐”仅限于视图Text?(我可以想象这是不可能的,因为它可能会破坏其他布局
  • 还向其他元素添加另一个“对齐方式”?

示例代码:

extension VerticalAlignment {
    /// A custom alignment for image titles.
    private struct TimeTextAlignment: AlignmentID {
        static func defaultValue(in context: ViewDimensions) -> CGFloat {
            // Default to bottom alignment if no guides are set.
            context[VerticalAlignment.firstTextBaseline]
        }
    }

    /// A guide for aligning titles.
    static let timeTextAlignment = VerticalAlignment(
        TimeTextAlignment.self
    )
}

struct ContentView: View {
    let textSize: Double = 70
    var body: some View {
        HStack(alignment: .timeTextAlignment) {
            ChildView(value: "5", textSize: textSize)
            ChildView(value: "0", textSize: textSize)
            ChildView(value: ":", textSize: textSize)
            ChildView(value: "0", textSize: textSize)
            ChildView(value: "0", textSize: textSize)
            ChildView(value: "0", textSize: textSize, small: true)
            ChildView(value: "0", textSize: textSize, small: true)
        }
        .padding()
        .frame(width: 300, height: 200)
    }
}

struct ChildView: View {
    let value: String
    let textSize: Double
    let small: Bool

    init(value: String, textSize: Double, small: Bool = false) {
        self.value = value
        self.textSize = textSize
        self.small = small
    }

    var body: some View {
        VStack {
            Button {

            } label: {
                Image(systemName: "chevron.up")
            }

            Spacer()

            Text(value)
                .font(.system(size: small ? textSize * 0.5 : textSize))
                .alignmentGuide(.timeTextAlignment) { context in
                    context[.firstTextBaseline]
                }

            Spacer()

            Button {

            } label: {
                Image(systemName: "chevron.down")
            }
        }
        .background(Color.red)
    }
}
Run Code Online (Sandbox Code Playgroud)

完整的游乐场可以在这里下载


作为一种“解决方法”,我可以想象我可以将 Views 重组为 3 HStacksinside 1 VStack