I'm trying to do some simple buttons, a button with or without a lock after it. The problem is when I add the Spacer(), it work correctly, but when I use an Image, the button goes to the left.
HStack() {
Spacer()
ZStack {
buttonBackground(isLocked: isLocked)
Text(level)
.foregroundColor(isLocked ? Color.gray : Color.white)
.frame(maxWidth: .infinity, alignment: .center)
}
.frame(width: screenWidth/2, height: 40)
if isLocked {
Image(systemName: "lock.fill")
.resizable()
.foregroundColor(.gray)
.frame(width: 30, height: 30, alignment: .topLeading)
} else {
Spacer()
}
}
Button with and without lock:
I can't make the button to stay in the middle when the Image is added.
I'm trying to do some simple buttons, a button with or without a lock after it. The problem is when I add the Spacer(), it work correctly, but when I use an Image, the button goes to the left.
HStack() {
Spacer()
ZStack {
buttonBackground(isLocked: isLocked)
Text(level)
.foregroundColor(isLocked ? Color.gray : Color.white)
.frame(maxWidth: .infinity, alignment: .center)
}
.frame(width: screenWidth/2, height: 40)
if isLocked {
Image(systemName: "lock.fill")
.resizable()
.foregroundColor(.gray)
.frame(width: 30, height: 30, alignment: .topLeading)
} else {
Spacer()
}
}
Button with and without lock:
I can't make the button to stay in the middle when the Image is added.
Share Improve this question edited Feb 17 at 21:28 Benzy Neez 21.2k3 gold badges14 silver badges36 bronze badges asked Feb 17 at 20:53 KelvinKelvin 11 bronze badge New contributor Kelvin is a new contributor to this site. Take care in asking for clarification, commenting, and answering. Check out our Code of Conduct.1 Answer
Reset to default 0When there is no image, the Spacer
on both sides of the button are keeping it centered. However, when the image is shown, there is a Spacer
on the left and the image on the right, so this is not likely to be balanced.
It's interesting that the button is pushed to the left when the image is present. If the full screen width would be available for showing the button and image then you would expect the Spacer
on the left to be pushing the content to the right. My guess is that there must be a VStack
that contains the buttons and this is being constrained to the width of the Menu button. This means, the Spacer
are only filling a very small width.
I would suggest these changes:
- Remove the
HStack
and remove theSpacer
. That just leaves theZStack
and the if/else with theImage
. - Add horizontal padding on both sides of the
ZStack
to reserve space for showing the image, if needed. - Show the image as an overlay with
alignment: .trailing
. - If you are setting a
.frame
with a fixed width on theVStack
that contains the buttons then remove this too. This might mean, you will need to add horizontal padding to the Menu button, or you could set a fixed width on the Menu button.
ZStack {
buttonBackground(isLocked: isLocked)
Text(level)
.foregroundStyle(isLocked ? .gray : .white)
}
.frame(width: screenWidth/2, height: 40)
.padding(.horizontal, 40)
.overlay(alignment: .trailing) {
if isLocked {
Image(systemName: "lock.fill")
.resizable()
.foregroundStyle(.gray)
.frame(width: 30, height: 30)
}
}
You may be using a GeometryReader
to measure the screen width. If so, the content inside the GeometryReader
will be aligned to the top-leading corner. To align the content to the center of the screen, add a frame with maxWidth: .infinity, maxHeight: .infinity
:
GeometryReader { proxy in
let screenWidth = proxy.size.width
VStack {
buttons(screenWidth: screenWidth)
}
.frame(maxWidth: .infinity, maxHeight: .infinity)
}