swiftuivertical-alignment

TopTrailing alignment is not working when trying to position the vStack inside of zStack


I am new to SwiftUI. I am trying to create a view like heart card but not being able to place the vStack of heart and letter at the top-right(topTrailing) corner of the rectangle.

var body: some View {
    ZStack {
        RoundedRectangle(cornerRadius: 5.0)
            .fill(.white)
            .stroke(.gray, style: StrokeStyle(lineWidth: 2.0))
            .frame(width: 100, height: 150)
            .shadow(color: Color(.black).opacity(0.3), radius: 5)
        
        VStack(spacing: 0) {
            Text("A")
                .font(.callout)
            
            Image(systemName: "heart.fill")
                .resizable()
                .frame(width: 10, height: 10)
        }.frame(alignment: .topTrailing)
    }
}

here is what I get as output. enter image description here

Can someone please help.


Solution

  • If you add a border to the VStack, you can see how the content of the VStack completely fills its frame:

    VStack(spacing: 0) {
        // as before
    }
    .frame(alignment: .topTrailing)
    .border(.orange)
    

    Screenshot

    What this .frame modifier is doing is to align the content of the VStack within a frame of the same size. But since the content already fills the frame, it makes no difference.

    With these changes it can be made to work:

    ZStack {
        RoundedRectangle(cornerRadius: 5.0)
            // as before, but without .frame
    
        VStack(spacing: 0) {
            // as before
        }
        .padding(8) // <- ADDED
        .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .topTrailing) // <- maxWidth and maxHeight added
    }
    .frame(width: 100, height: 150) // <- moved from RoundedRectangle
    

    So what this does is to fix the size of the ZStack to the card size. A RoundedRectangle (like any Shape) is greedy, so it expands to fill the same space. The .frame modifier on the VStack now causes it to expand to the size of the ZStack and the alignment parameter aligns the content as you intended it to.

    Screenshow or with a border on the VStack: enter image description here