mezo
mezo

Reputation: 453

Different verticalAlignment in HStack in SwiftUI

I'm trying to create simple cell layout in SwiftUI but I somehow stumbled on problem how to define different vertical alignments of elements in same HStack:

This is basically what I'm trying to achieve: enter image description here

Whole view should be a cell, where there are some arbitrary paddings(24 on top, 20 at bottom). What is important is following:

  1. HStack contains icon (red), vstack (title and description) and another icon (green)
  2. Red icon should be aligned to the top of the HStack as well as vstack with texts
  3. Green icon should be centered in the whole view

I've tried to achieve this with following code:

VStack(spacing: 0) {
    HStack(alignment: .top, spacing: 24) {
        Image(nsImage: viewModel.icon)
            .frame(width: 20.0, height: 20.0)

        VStack(alignment: .leading, spacing: 4) {
            Text(viewModel.title)
            Text(viewModel.text)
        }
        
        Spacer()

        Image(nsImage: "viewModel.next")
    }
    .padding([.top], 24)
    .padding([.bottom], 20)
    Divider()
}

Without luck as obviously the green icon is also aligned to the top. I've tried to mess around with layout guides without success.

Another solution I've tried is

    VStack(spacing: 0) {
    HStack(alignment: .top, spacing: 24) {
        Image(nsImage: viewModel.icon)
            .frame(width: 20.0, height: 20.0)

        VStack(alignment: .leading, spacing: 4) {
            Text(viewModel.title)
            Text(viewModel.text)
        }
        
        Spacer()

        VStack {
            Spacer()
            Image(nsImage: "viewModel.next")
            Spacer()
        }
    }
    .padding([.top], 24)
    .padding([.bottom], 20)
    Divider()
}

which doesn't work either as I have more of these 'cells' in super view and their height is stretched to fill the superview.

Any idea how to achieve this?

Upvotes: 2

Views: 709

Answers (1)

ScottM
ScottM

Reputation: 10404

I would treat the left-hand image and text as a single, top-aligned HStack, then put that in another HStack aligned centrally with the right-hand image. In shorthand, omitting spacing etc.:

HStack(alignment: .center) {
  HStack(alignment: .top) {
    Image(nsImage: ...)
    VStack(alignment: .leading) {
      Text(...)
      Text(...)
    }
  }
  Spacer()
  Image(nsImage: ...)
}

That way, you only have a spacer working in the horizontal axis, so your overall vertical frame will be determined by the content alone.

Upvotes: 1

Related Questions