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

纵然是瞬间 提交于 2021-02-11 14:45:24

问题


It could be a simple case, but I couldn't find a solution.

Here is my code, using the GeometryReader to set the relative layout of SwiftUI view size like Image. The issue in on the last VStack, I want to background of Text to go to the right end of VStack. Thus, I set it as Text("Haibo: asdasd").frame(maxWidth: .infinity) but after that I found the text became to horizontal centered and not followed the VStack alignment: .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()
    }
}

Well, please see the screenshot for better understanding, the Text("Haibo: asdasd") is centered in the yellow area. How could let it to be keep leading alignment?


回答1:


This is a fairly confusing aspect of SwiftUI. The VStack alignment specifies how its elements align within the VStack frame, while the Text.frame alignment specifies how the text will align within the Text.frame.

I've found it helpful to add some borders as I'm debugging:

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)
}

Now you can see that the Text with maxWidth: .infinity has a frame that spans the entire width of the VStack frame. The text frame is aligned leading, but the text within defaults to a center alignment.

It's worth mentioning here that the "jobs..." text is also center aligned to its text frame, but it's not obvious because the frame is sized to the text only, then the text frame itself is leading aligned within the VStack frame.

Now try this:

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)
}

The text frame is still the full-width of the VStack frame, but the text is now aligned leading within the text frame.

Here's the snippet without the borders:

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

Here's an article I found helpful for sorting out how alignment works:

Alignment Guides in SwiftUI




回答2:


You should add .leading alignment to its frame, like

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


来源:https://stackoverflow.com/questions/60800624/how-to-keep-text-as-leading-alignment-after-set-text-framemaxwidth-infinity

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!