Reputation: 1718
Using SwiftUI, I am trying to center a View
on the screen and then give it a header and/or footer of variable heights.
Using constraints it would look something like this:
let view = ...
let header = ...
let footer = ...
view.centerInParent()
header.pinBottomToTop(of: view)
footer.pinTopToBottom(of: view)
This way, the view
would always be centered on the screen, regardless of the size of the header and footer.
I cannot figure out how to accomplish this with SwiftUI. Using any type of HStack
or VStack
means the sizes of the header
and footer
push around the view
. I would like to avoid hardcoding any heights since the center view
may vary in size as well.
Any ideas? New to SwiftUI so advice is appreciated!
Upvotes: 5
Views: 5187
Reputation: 1083
Here's the code:
struct ContentView: View {
var body: some View {
GeometryReader { geometry in
VStack(alignment: .leading) {
Rectangle()
.fill(Color.gray)
.frame(width: geometry.size.width, height: geometry.size.height * 0.1, alignment: .center)
Text("Center")
.frame(width: geometry.size.width, height: geometry.size.height * 0.2, alignment: .center)
Rectangle()
.fill(Color.gray)
.frame(width: geometry.size.width, height: geometry.size.height * 0.1, alignment: .center)
}
}
}
}
using GeometryReader
you can apply the dynamic size for your views.
also here is screenshot for above code
Upvotes: 1
Reputation: 257693
If I correctly understood your goal (because, as @nayem commented, at first time seems I missed), the following approach should be helpful.
Code snapshot:
extension VerticalAlignment {
private enum CenteredMiddleView: AlignmentID {
static func defaultValue(in dimensions: ViewDimensions) -> CGFloat {
return dimensions[VerticalAlignment.center]
}
}
static let centeredMiddleView = VerticalAlignment(CenteredMiddleView.self)
}
extension Alignment {
static let centeredView = Alignment(horizontal: HorizontalAlignment.center,
vertical: VerticalAlignment.centeredMiddleView)
}
struct TestHeaderFooter: View {
var body: some View {
ZStack(alignment: .centeredView) {
Rectangle().fill(Color.clear) // !! Extends ZStack to full screen
VStack {
Header()
Text("I'm on center")
.alignmentGuide(.centeredMiddleView) {
$0[VerticalAlignment.center]
}
Footer()
}
}
// .edgesIgnoringSafeArea(.top) // uncomment if needed
}
}
struct Header: View {
var body: some View {
Rectangle()
.fill(Color.blue)
.frame(height: 40)
}
}
struct Footer: View {
var body: some View {
Rectangle()
.fill(Color.green)
.frame(height: 200)
}
}
struct SwiftUIView_Previews: PreviewProvider {
static var previews: some View {
TestHeaderFooter()
}
}
Upvotes: 3
Reputation: 52
put Spacer()
between header view and footer view.
headerview()
Spacer()
footerview()
Upvotes: -1