Hudi Ilfeld
Hudi Ilfeld

Reputation: 2045

.zIndex() only applying to sibling views inside VStack but not to views outside

This is the layout I have:

VStack {
 Image()
 
 HStack { 
   
   Image()

   VStack {
     CustomDropdown() //expands views till bottom of screen
       .zIndex(1)
 
     AnotherView()
   }

 }

 MyButton()

}

As you can see, I need my CustomDropdown to overlap all views below it on the screen, thus I set it's zIndex to 1.

The Issue:

The CustomDropdown is only overlapping it's sibling views below it that share the same VStack. However it's able to overlap the bottom MyButton since they are not sharing the same VStack.

I tried setting the MyButtons index to 0 but of course that took no affect.

I am fresh in SwiftUI and I am sure I am missing a simple solution to this task.

Thanks in advance.

EDIT:

My objective is to find a way such that the dropDown view will be able to handle the Z logic without help from Views around it I.E setting the Z index of other views in the screen

Upvotes: 6

Views: 3410

Answers (1)

DonMag
DonMag

Reputation: 77423

Your current view hierarchy has 3 "top-level" elements:

Image
HStack
MyButton

So, to get anything contained inside the HStack to be "on-top-of" MyButton (or any other following elements), you have to raise the z-index of HStack.

Here's a simple example - tapping on the Green rectangle will toggle its Height between 80 and 300:

struct ExpandableView: View {
    @State var expanded = false

    var body: some View {
        VStack {

            // Red view
            Rectangle()
                .fill(Color.red)
                .frame(width: 300, height: 80, alignment: .top)
            
            HStack {
                
                // Green view (your CustomDropdown)
                Rectangle()
                    .fill(Color.green)
                    .frame(width: 100, height: expanded ? 300 : 80, alignment: .top)
                    .onTapGesture {
                        expanded.toggle()
                    }
                
            }
            .frame(width: 300, height: 120, alignment: .top)
            
            // Blue view (your MyButton)
            Rectangle()
                .fill(Color.blue)
                .frame(width: 200, height: 100, alignment: .top)
            
        }
        
    }

}

As you've experienced, this is the result:

enter image description here enter image description here

It doesn't matter what you do with the z-index of the Green view... it will only affect its hierarchy-order within the HStack.

But, if we modify the z-index of the HStack:

struct ExpandableView: View {
    @State var expanded = false

    var body: some View {
        VStack {

            // Red view
            Rectangle()
                .fill(Color.red)
                .frame(width: 300, height: 80, alignment: .top)
            
            HStack {
                
                // Green view (your CustomDropdown)
                Rectangle()
                    .fill(Color.green)
                    .frame(width: 100, height: expanded ? 300 : 80, alignment: .top)
                    .onTapGesture {
                        expanded.toggle()
                    }
                
            }
            .frame(width: 300, height: 120, alignment: .top)
            // bring HStack above following elements (Blue Rectangle)
            .zIndex(1)
            
            // Blue view (your MyButton)
            Rectangle()
                .fill(Color.blue)
                .frame(width: 200, height: 100, alignment: .top)
            
        }
        
    }

}

we get this:

enter image description here enter image description here

Upvotes: 4

Related Questions