Consider the following view:
var body: some View {
GeometryReader { geo in
ZStack {
HStack(spacing: 0) {
VStack {
Text("The number two")
Text("2")
.font(.largeTitle)
}
.frame(maxWidth: .infinity)
.background(Color.purple)
VStack {
Text("The number eight")
Text("8")
.font(.largeTitle)
}
.frame(maxWidth: .infinity)
.background(Color.green)
}
Button(action: {
print("Button tapped!")
}) {
Text("NEXT")
}
.padding()
.background(Color.orange)
.foregroundColor(.white)
.clipShape(RoundedRectangle(cornerRadius: 10))
.position(x:geo.size.width, y:geo.size.height)
.padding(16)
}
.frame(maxWidth: .infinity, maxHeight: .infinity)
.background(.gray)
}
}
On all devices, I want the button positioned in the lower right of the screen, 16 pixels from the trailing edge, and 16 pixels from the bottom edge, regardless of what else is on the screen (in the ZStack). What is the best practice to achieve that? Here's what it looks like now:
Your current code is behaving the way it is because position
in SwiftUI positions the center of the View
. But, you don't actually need position
or GeometryReader
to do this.
You can assign a frame
to the orange button and align it to bottomTrailing
:
struct ContentView: View {
var body: some View {
ZStack {
HStack(spacing: 0) {
VStack {
Text("The number two")
Text("2")
.font(.largeTitle)
}
.frame(maxWidth: .infinity)
.background(Color.purple)
VStack {
Text("The number eight")
Text("8")
.font(.largeTitle)
}
.frame(maxWidth: .infinity)
.background(Color.green)
}
Button(action: {
print("Button tapped!")
}) {
Text("NEXT")
}
.padding()
.background(Color.orange)
.foregroundColor(.white)
.clipShape(RoundedRectangle(cornerRadius: 10))
.padding(16)
.frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .bottomTrailing) // <-- Here
}
.frame(maxWidth: .infinity, maxHeight: .infinity)
.background(.gray)
}
}