Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to align items to top inside VStack in SwiftUI?

Tags:

ios

swiftui

I just started with swiftui and I am facing issues in ui alignment. The following code creates a space from top of the image

VStack(alignment: .leading) {
        Image(item.imageUrl)
              .resizable()
              .aspectRatio(contentMode: .fit)
              .frame(width: 72, height: 72, alignment: .top).padding(.top,0)
        Text("\(item.name)").font(Font.system(size:12, design: .default))
             .multilineTextAlignment(.center)
             .frame(maxWidth: .infinity).lineLimit(2)    
        }
}

I can see that VStack accepts param alignment , but it's horizontal alignment. What I need is that the Image should stick to the top of its superview. Is there a way to do this without the use of Spacer().

Like in react-native we used to have justifyContent and alignItems for both horizontal and vertical alignment of children.

UPDATE:

The same issue exists for Text too, or any view. E.g. This code places the two text in center of the view

 VStack(alignment: .leading, spacing: 0) {
        Text("line 1")
        Text("line 2")
 }

enter image description here

The param alignment in VStack is for horizontal alignment.

Now to align these texts to top, the only way I can think of is by introducing Spacer() like this:

struct MyCustomView:View {
  var body: some View {
    VStack(alignment: .leading, spacing: 0) {
      Text("line 1")
      Text("line 2")
      Spacer()
    }
 }

This does solves the problem temporarily:

enter image description here

But the spacer will create problem in complex views, lets say another developer wants to add a custom view (line 3 in this case) just below my view, the spacer will create additional space in between

VStack {
     MyCustomView()
     Text("line 3")
 }

enter image description here

Is there a better way that my child views (and subsequent views) inside a VStack remains aligned to top without the spacer?

like image 666
Romit Kumar Avatar asked Dec 22 '22 16:12

Romit Kumar


1 Answers

You can try using .frame() modifier to make the VStack() take full size in it superview. In frame you can align your content topLeading

var body: some View {
    VStack(alignment: .leading, spacing: 0) {
        Text("line 1")
        Text("line 2")
    }
    .frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: .infinity, alignment: .topLeading)
    .border(Color.red)
}

No Spacer needed for that solution

like image 120
davidev Avatar answered Jan 09 '23 17:01

davidev