Will
Will

Reputation: 5470

Prevent movement of top item in VStack

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

Upvotes: 1

Views: 90

Answers (2)

aheze
aheze

Reputation: 30318

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
)

Upvotes: 1

Will
Will

Reputation: 5470

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")
            }
        
    }
}

Upvotes: 0

Related Questions