gridviewswiftuiandroid-gravitylazyvgridlazyhgrid

How to make SwiftUI Text multilineTextAlignment start from Top and Center


enter image description here

How can I make the image and text alignment same as 3 other in SwiftUI LazyVGrid as I expected in image below?

I think the problem is how to make the text start from top if the text is multiline. In Android I can use gravity="top|center" but in SwiftUI I use .multilineTextAlignment(.center) but the result not as I expected.

enter image description here

Here what I just try in my code:

      LazyVGrid(columns: gridItemLayout, spacing: 0) {
          ForEach((0...7), id: \.self) { i in
               VStack {
                    RemoteImageView(url: vm.listService[i].image_uri)
                        .frame(width: 100, height: 100)
                    Text(vm.listService[i].name)
                        .font(.body)
                        .multilineTextAlignment(.center)
                        .frame(maxWidth: .infinity, alignment: .center)
               }
         }
      }
      .padding(.horizontal, 25.0)

Solution

  • For the Text's frame, you need to:

    1. set maxHeight to .infinity, so it can expand vertically too
    2. set alignment to .top, so it's aligned to the top
    let names = ["Hi", "Hello world", "Long long text"]
    
    let gridItemLayout = [
       GridItem(.adaptive(minimum: 80))
    ]
    
    var body: some View {
        
        LazyVGrid(columns: gridItemLayout, spacing: 0) {
            ForEach((0...7), id: \.self) { i in
                VStack {
                    Image(systemName: "folder")
                    .frame(width: 100, height: 100)
                    .background(Color.green)
                    Text(names.randomElement() ?? "")
                    .font(.body)
                    .multilineTextAlignment(.center)
                    
                    /// here!
                    .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .top)
                }
            }
        }
        .padding(.horizontal, 25.0)
    }
    

    Result:

    Grid of elements composed of an Image on top of a Text. The Image's y position is always the same, while the Text expands down when it has multiple lines.