1

I have a ZStack in which an Image is presented. The image needs to be scaled in some cases.

I am failing on aligning the scaled image on the bottom of the ZStack, it is always presented in the middle.

I tried ZStack(alignment: .bottom) in combination with .alignmentGuide(.bottom) for the image, but this does not change the outcome.

Also putting a VStack around the image and placing a Spacer() above it does not change the result.

The HStack is not relevant and is only shown, because I need an ZStack in this construct. But The main issue is with the VStack, that it does not move after scaling in the Space of the ZStack.

It seems like .scaleEffect just uses position and frame of the original image and places the scaled image in the middle. Is this a limitation of scaleEffect? What other function can be used?

This is my View (reduced code): // I colored the background purple, to show the full size of the ZStack

var body: some View {
    ZStack(alignment: .bottom) {
        Color.purple
        Image(battlingIndividual.getMonster().getStatusImageName(battlingIndividual.status))
            .resizable()
            .scaledToFill()
            .scaleEffect(battlingIndividual.getMonster().size.scaleValue)
        HStack() {
            SkillViews(battlingIndividual: battlingIndividual)
            Spacer()
        }
      }
}

The outcome is this:

current outcome

But it should look like this: desired outcome

EDIT: I added a Background to the image, in order to show that the image is centered in the ZStack. Image-Background in gray


Solution: We don´t need an alignment in this case, we need an anchor:

.scaleEffect(battlingIndividual.getMonster().size.scaleValue, anchor: .bottom)

Solution Image: enter image description here

Nathanael Tse
  • 171
  • 13

3 Answers3

1

I figured it out. .scaleEffect uses its own anchor, which can be set to .bottom.

scaleEffect(_:anchor:) Apple Developer

Therefore I needed only to add "ancor: .bottom" to the scaleEffect.

.scaleEffect(battlingIndividual.getMonster().size.scaleValue, anchor:
.bottom)

for the following result: enter image description here

Nathanael Tse
  • 171
  • 13
0

Please, put your Image in a VStack and a Spacer() above the image and your Images will be on the bottom of the Stack. The alignment .bottom is only to aline multiple views with each other, but you are not having multiple views in your Stack. The HStack doesn't count for the alignment.

If I try this out in my example and scale the image down,

import SwiftUI

struct ContentView: View {
    var body: some View {
        ZStack {
            Color.purple
            
            VStack {
                Spacer()
                
                Image(systemName: "ladybug")
                    .resizable()
                    .scaledToFit()
                    .frame(width: 100, height: 100, alignment:                 
                HStack {
                    Image(systemName: "hare")
                        .resizable()
                        .frame(width: 50, height: 50)
                    Image(systemName: "hare")
                        .resizable()
                        .frame(width: 50, height: 50)
                    Image(systemName: "hare")
                        .resizable()
                        .frame(width: 50, height: 50)
                    Spacer()
                }
            }
        }
    }
}

I get this.

enter image description here

Kind regards, MacUserT

MacUserT
  • 1,760
  • 2
  • 18
  • 30
  • I tried the spacer too, but it didnt work. VStack() { Spacer(), Image() } - same result – Nathanael Tse Jan 23 '21 at 14:54
  • Can you tell me what the SkillViews is doing? – MacUserT Jan 23 '21 at 15:51
  • The skill view presents another set of up to 10 images at the left side of the ZStack. Here the alignment works properly and the Spacer() works. The images are centered here as well, of course, if one image is presented it is in the middle, if two images are presented, one is above and one is below the middle. – Nathanael Tse Jan 23 '21 at 16:36
  • you do not scale the image. if you scale the image the bug will be smaller but always show up in the middle instead of moving down... – Nathanael Tse Jan 24 '21 at 00:25
  • I scaled the image down and it is still at the bottom of the view. – MacUserT Jan 24 '21 at 09:38
0

I assume this view container ZStack is a one cell view, so you need to align not ZStack which tights to content, but entire HStack containing those monster cells, like

HStack(alignment: .bottom) {    // << here !!
   ForEach ... {
      MonsterCellView()
   }
}
Asperi
  • 228,894
  • 20
  • 464
  • 690
  • you are right, I am using a LazyHStack, but also the "alignment: .bottom" there does not help. It should be in the ZStack.Because when I put text above the Image, a Spacer inbetween, the Image still does not move to the bottom but keeps its space... – Nathanael Tse Jan 23 '21 at 15:12