14

As a root view of my app, I have a ZStack, and I would like to add two floating bars, one to the bottom, and one to the top of the viewport.

With a single bar it's easy (ZStack(alignment: .top)), but is there a way to add multiple descendants, and have one aligned to the top, and a second one to the bottom?

I tried removing alignment from ZStack, and adding .frame(alignment: .top) / .frame(alignment: .bottom) to the children, but this didn't do anything.

Yes, it could be hacked around by wrapping a top-aligned ZStack with another, bottom-aligned one, but it seems rather inelegant.

Tomáš Kafka
  • 4,405
  • 6
  • 39
  • 52

3 Answers3

37

Here is possible approach

ZStack {

 // content here

}
.overlay(YourTopView(), alignment: .top)
.overlay(YourBottomView(), alignment: .bottom)

Other possible variant is to use one .overlay with VStack having two views and Spacer in between.

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
Asperi
  • 228,894
  • 20
  • 464
  • 690
3

You can just add a VStack inside your ZStack like this

ZStack {
    VStack {
        YourTopView()
        Spacer()
        YourBottomView()
    }
}
Hieu Dinh
  • 692
  • 5
  • 18
  • 1
    Thank you, this also works - I originally expected the spacer to block clicks into underlying content, but it apparently doesn't. – Tomáš Kafka Jun 01 '21 at 21:18
1

Here's another approach that allows overlap of the top and bottom-aligned views.

ZStack() {
    VStack() {
        topView()
        Spacer()
    }
    VStack() {
        Spacer()
        bottomView()
    }
}
Bruce Webster
  • 171
  • 10