Home > Software engineering >  Prevent movement of top item in VStack
Prevent movement of top item in VStack

Time:11-01

I'm trying to build widget with what I imagined to be a fair simple layout.

 ___________________
|                   |
| Title.            | 
| Subtitle          |      Static Content (more or less)  
|___________________|
|                   |
| 1           Today |
|                   |
| 2        Tomorrow |      Dynamic Content
|                   |
| 3       In 1 hour |
|___________________|

The issue is if any of the dynamic content is too big, it pushes the top content bar out the top of the widget, whereas I'd rather it grew out of the bottom. I can demonstrate this with this example:

enter image description here enter image description here enter image description here

As you can can see, as green gets too big, it pushes pink off the screen. I can't find a way to fix this.

I've tried ZStack(alignment: .top), I've tried layoutPriority, I've tried fixedSize and I've tried Spacer

CodePudding user response:

I don't know why, but this worked:

GeometryReader { proxy in
    
    VStack(spacing: 0) {
        Rectangle()
            .foregroundColor(.pink)
            .frame(height: 40)
            .overlay {
                Text("Height: 40")
            }
        Rectangle()
            .foregroundColor(.green)
            .frame(height: 180)
            .overlay {
                Text("Height: 180")
            }
        
    }
}

CodePudding user response:

Your GeometryReader answer works because GeometryReader aligns its content to the top by default. But since you don't use the proxy var, it might make more sense to use an overlay instead.

Color.clear.overlay(alignment: .top) { /// set alignment to `.top`!
    VStack(spacing: 0) {
        Rectangle()
            .foregroundColor(.pink)
            .frame(height: 40)
            .overlay {
                Text("Height: 40")
            }
        Rectangle()
            .foregroundColor(.green)
            .frame(height: 180)
            .overlay {
                Text("Height: 180")
            }
    }
}

If you need to support iOS 13-15, try overlay(_:alignment:):

Color.clear.overlay(
    VStack(spacing: 0) {
        Rectangle()
            .foregroundColor(.pink)
            .frame(height: 40)
            .overlay {
                Text("Height: 40")
            }
        Rectangle()
            .foregroundColor(.green)
            .frame(height: 180)
            .overlay {
                Text("Height: 180")
            }
    },
    alignment: .top
)
  • Related