admin管理员组

文章数量:1301538

I am creating a food card in SwiftUI, but I have an issue with element positioning. I need the bottom HStack (with calories and a heart icon) to be aligned with the bottom of the card, but right now, it is positioned higher than expected.

How can I move the HStack down so that it is placed at the bottom of the card, considering that the VStack already contains an image, name, and description?

VStack(alignment: .leading) {
  Text(name)
    .font(.title3)
    .fontWeight(.semibold)
    .padding(.top, 170)
        
  Text(description)
    .font(.caption)
      
  HStack(spacing: 84) {
    Text("\(calories) Kcal")
      .font(.body)
      .fontWeight(.semibold)
        
    Image(systemName: "heart.fill")
      .font(.title)
      .fontWeight(.semibold)
      .foregroundStyle(.my)
  }
}
.frame(maxWidth: 227, maxHeight: 349)
.background(.red)
.clipShape(
  .rect(
    topLeadingRadius: 120,
    bottomLeadingRadius: 30,
    bottomTrailingRadius: 30,
    topTrailingRadius: 120
  )
)
.shadow(color: .black.opacity(0.1), radius: 10, y: 4)
.overlay {
  Image(.saladAllotment)
    .resizable()
    .scaledToFit()
    .frame(maxWidth: 227)
    .padding(.top, -140)
    .shadow(color: .black.opacity(0.3), radius: 10, y: 4)
}

I am creating a food card in SwiftUI, but I have an issue with element positioning. I need the bottom HStack (with calories and a heart icon) to be aligned with the bottom of the card, but right now, it is positioned higher than expected.

How can I move the HStack down so that it is placed at the bottom of the card, considering that the VStack already contains an image, name, and description?

VStack(alignment: .leading) {
  Text(name)
    .font(.title3)
    .fontWeight(.semibold)
    .padding(.top, 170)
        
  Text(description)
    .font(.caption)
      
  HStack(spacing: 84) {
    Text("\(calories) Kcal")
      .font(.body)
      .fontWeight(.semibold)
        
    Image(systemName: "heart.fill")
      .font(.title)
      .fontWeight(.semibold)
      .foregroundStyle(.my)
  }
}
.frame(maxWidth: 227, maxHeight: 349)
.background(.red)
.clipShape(
  .rect(
    topLeadingRadius: 120,
    bottomLeadingRadius: 30,
    bottomTrailingRadius: 30,
    topTrailingRadius: 120
  )
)
.shadow(color: .black.opacity(0.1), radius: 10, y: 4)
.overlay {
  Image(.saladAllotment)
    .resizable()
    .scaledToFit()
    .frame(maxWidth: 227)
    .padding(.top, -140)
    .shadow(color: .black.opacity(0.3), radius: 10, y: 4)
}
Share edited Feb 11 at 9:11 Benzy Neez 22.1k3 gold badges14 silver badges41 bronze badges asked Feb 11 at 5:15 Yuldashev FazliddinYuldashev Fazliddin 1 0
Add a comment  | 

3 Answers 3

Reset to default 0

you could try using a Spacer() just before HStack(spacing: 84) {...}. That will push the HStack to the bottom.

You can move the bottom HStack down by using Spacer() inside the VStack. This ensures that the HStack is pushed to the bottom while keeping the other elements aligned properly. Here's how you can achieve it:

let contentHeight: CGFloat = 350
let contentWidth: CGFloat = 230

var body: some View {
    ZStack(alignment: .top) {
        VStack(alignment: .leading) {
            Spacer() // Pushes content upwards

            Text(name)
                .font(.title3)
                .fontWeight(.semibold)
                .padding(.top, 30)

            Text(description)
                .font(.caption)

            Spacer() // Pushes HStack down

            HStack(spacing: 84) {
                Text("\(calories) Kcal")
                    .font(.body)
                    .fontWeight(.semibold)

                Image(systemName: "heart.fill")
                    .font(.title)
                    .fontWeight(.semibold)
                    .foregroundStyle(.yellow)
            }
            .padding(.bottom)
        }
        .shadow(color: .black.opacity(0.1), radius: 10, y: 4)
        .frame(width: contentWidth, height: contentHeight)
        .background(Color.red)
        .clipShape(
            RoundedRectangle(cornerRadius: 30, style: .continuous)
        )

        Image(.saladAllotment)
            .resizable()
            .scaledToFill()
            .frame(width: contentWidth, height: contentHeight / 2)
            .offset(y: -contentHeight / 3.5)
            .shadow(color: .black.opacity(0.3), radius: 10, y: 4)
    }
}

To push the HStack down, you can apply a frame with maxHeight: .infinity. However, this also pushes the title up, which makes it go behind the image.

To sort out the placement, I would suggest applying the overlay using alignment: .top. Then you just need to add appropriate padding to move the title down below the image.

VStack(alignment: .leading) {
    Text(name)
        .font(.title3)
        .fontWeight(.semibold)
        .padding(.top, 240) // 

本文标签: iosHow to Move Bottom HStack Down in SwiftUI Food Card DesignStack Overflow