如何在设置 Text().frame(maxWidth: .infinity) 后将 Text 保持为前导对齐

How to keep Text as leading alignment after set Text().frame(maxWidth: .infinity)

这可能是一个简单的案例,但我找不到解决方案。

这是我的代码,使用 GeometryReader 设置 SwiftUI 视图大小的相对布局,如 Image。问题在最后一个 VStack 上,我想让 Text 的背景转到 VStack 的右端。因此,我将其设置为 Text("Haibo: asdasd").frame(maxWidth: .infinity) 但之后我发现文本变为水平居中并且不遵循 VStack 对齐方式:.leading.

import SwiftUI

struct ContentView: View {
    var body: some View {

        GeometryReader { geo in
            HStack(alignment: .top, spacing: 12) {
                Image("Alan shore").resizable().frame(width: geo.size.width / 6, height: geo.size.width / 6).cornerRadius(4)

                VStack(alignment: .leading, spacing: 10) {

                   // name
                   Text("Haibo")
                   // content
                   Text("Think ThinkThink ThinkThink ThinkThink ThinkThink ThinkThink ThinkThink ThinkThink Think")
                   // 九宫格
                   VStack(spacing: 6) {

                       HStack(spacing: 6) {
                           Image("Little girl").resizable().frame(width: geo.size.width / 4.7, height: geo.size.width / 4.7)
                           Image("Little girl").resizable().frame(width: geo.size.width / 4.7, height: geo.size.width / 4.7)
                           Image("Little girl").resizable().frame(width: geo.size.width / 4.7, height: geo.size.width / 4.7)
                       }
                       HStack(spacing: 6) {
                           Image("Little girl").resizable().frame(width: geo.size.width / 4.7, height: geo.size.width / 4.7)
                           Image("Little girl").resizable().frame(width: geo.size.width / 4.7, height: geo.size.width / 4.7)
                           Image("Little girl").resizable().frame(width: geo.size.width / 4.7, height: geo.size.width / 4.7)
                       }
                       HStack(spacing: 6) {
                           Image("Little girl").resizable().frame(width: geo.size.width / 4.7, height: geo.size.width / 4.7)
                           Image("Little girl").resizable().frame(width: geo.size.width / 4.7, height: geo.size.width / 4.7)
                           Image("Little girl").resizable().frame(width: geo.size.width / 4.7, height: geo.size.width / 4.7)
                       }
                   }

                   // Time, Action
                   HStack {
                       Text("5 hour ago")
                       Spacer()
                       Image("moment-action")
                   }

                   // Comment
                   VStack(alignment: .leading) {
                       Text("Haibo: asdasd").frame(maxWidth: .infinity)
                       Text("Jobs: WDC WDC WDC WDCWWWWW")
                   } //.padding(.init(top: 6, leading: 6, bottom: 6, trailing: 12))
                       .background(Color.yellow)
                   .cornerRadius(3)
                }
            } .padding(.init(top: 12, leading: 12, bottom: 12, trailing: 30))
        }
    }
}


struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

好吧,请看截图以便更好地理解,Text("Haibo: asdasd") 位于黄色区域的中心。怎么让它一直保持领先?

您应该在其框架中添加 .leading 对齐方式,例如

 VStack(alignment: .leading) {
           Text("Haibo: asdasd").frame(maxWidth: .infinity, alignment: .leading)
           Text("Jobs: WDC WDC WDC WDCWWWWW")
       }

这是 SwiftUI 的一个相当令人困惑的方面。 VStack 对齐指定其元素如何在 VStack 框架内对齐,而 Text.frame 对齐指定文本将如何在 Text.frame.

内对齐

我发现在调试时添加一些边框很有帮助:

VStack(alignment: .leading) {
    Text("Haibo: asdasd")
        .frame(maxWidth: .infinity)
        .border(Color.red , width: 2.0)
    Text("Jobs: WDC WDC WDC WDCWWWWW")
        .border(Color.green , width: 2.0)
}

现在您可以看到具有 maxWidth: .infinity 的文本具有跨越 VStack 框架的整个宽度的框架。文本框 前导对齐,但其中的文本默认居中对齐。

这里值得一提的是,"jobs..." 文本也与其文本框架居中对齐,但这并不明显,因为框架仅根据文本调整大小,然后文本框架本身在VStack 框架。

现在试试这个:

VStack(alignment: .leading) {
    Text("Haibo: asdasd")
        .frame(maxWidth: .infinity, alignment: .leading)
        .border(Color.red , width: 2.0)
    Text("Jobs: WDC WDC WDC WDCWWWWW")
        .border(Color.green , width: 2.0)
}

文本框架仍然是 VStack 框架的全宽,但文本现在在文本框架内以领先的方式对齐。

这是没有边框的片段:

VStack(alignment: .leading) {
    Text("Haibo: asdasd")
        .frame(maxWidth: .infinity, alignment: .leading)
    Text("Jobs: WDC WDC WDC WDCWWWWW")
}

我发现这是一篇有助于理清对齐方式的文章:

Alignment Guides in SwiftUI