0

I'm working with a card-like view, and I would essentialy like to know the minimum height needed to house the elements, and then add a border around that.

this becomes difficult since VStack and HStack seem to want to take up the most space possible, so I need to manually insert a .frame(...) to coercse this to work, but that makes it very unflexible.

In the picture I'm highlighting the VStack which, as you can see, is overfilling beyond the constraints of the 48px frame height.

code

var body: some View {
    HStack(spacing: 0) {
      Image("cocktail")
        .resizable()
        .scaledToFit()
        .padding(Size.Spacing.unit * 2)
        .background(self.color)
        .cornerRadius(8)
        .overlay(
          RoundedRectangle(cornerRadius: 8)
            .stroke(self.color)
      )


      HStack(spacing: 0) {
        VStack(alignment: .leading) {
          Text("Negroni").font(.headline)
          Spacer()
          HStack {
            Tag(name: "bitter")
            Tag(name: "sweet")
            Tag(name: "strong")
          }
        }
        .padding(.leading, 10)
        Spacer()
      }
    }
    .padding(Size.Spacing.unit * 2)
    .frame(height: 48.0)
  }

enter image description here

austin
  • 405
  • 4
  • 12

2 Answers2

0

maybe i misunderstand you, but i tried your example...unfortunately it was not compilable, so i had to change some things. but as you can see the result (vstack - yellow) is not taking to much space, maybe because of your padding?

struct ContentView: View {
    var body: some View {
      HStack(spacing: 0) {
        Image("cocktail")
          .resizable()
          .scaledToFit()
      //    .padding(Size.Spacing.unit * 2)
            .background(Color.blue)
          .cornerRadius(8)
          .overlay(
            RoundedRectangle(cornerRadius: 8)
                .stroke(Color.yellow)
        )


        HStack(spacing: 0) {
          VStack(alignment: .leading) {
            Text("Negroni").font(.headline)
            Spacer()
            HStack {
              Text("bitter")
              Text("sweet")
              Text("strong")
            }
          }
          .background(Color.yellow)
          .padding(.leading, 10)
          Spacer()
        }.background(Color.red)
      }
   //   .padding(Size.Spacing.unit * 2)
      .frame(height: 48.0)
    }
}

enter image description here

Chris
  • 7,579
  • 3
  • 18
  • 38
  • thanks, this is much better, but not exactly what I was trying to do. Let me rephrase a bit. this works to make sure the text is not taking up too much space, but I also wanted the blue image to fill to that minimum height. Ideally without the `.frame(height: 40)` being hard coded – austin Jun 09 '20 at 15:27
0

since VStack and HStack seem to want to take up the most space possible

This assumption is incorrect - by default stacks are tight to content and content tight to minimum with default padding between UI elements. In provided code it is Spacer() responsibility on expanding to max available space. So to make minimum space for content, highlighted VStack should be changed as follows:

VStack(spacing: 0, alignment: .leading) {
  Text("Negroni").font(.headline)
  HStack {
    Tag(name: "bitter")
    Tag(name: "sweet")
    Tag(name: "strong")
  }
}
Asperi
  • 228,894
  • 20
  • 464
  • 690