If I have a VStack
with limited height and the contents of the VStack
require more height than what's available, is there a way I can control which items get clipped?
I created the short sample below to illustrate.
I'd like "Bottom" to be clipped instead of the black rectangle when the toggle is set to "Open".
I've tried .fixedSize
, .layoutPriority
and a number of other things.
import SwiftUI
struct ContentView: View {
@State var isOpen: Bool = false
var body: some View {
container
}
@ViewBuilder var container: some View {
VStack {
header
content
}
.frame(width: 300, height: 110)
.background(.gray)
.cornerRadius(20)
}
@ViewBuilder var header: some View {
RoundedRectangle(cornerRadius: 5)
.frame(width: 50, height: 10)
}
@ViewBuilder var content: some View {
VStack(alignment: .leading) {
Picker("mypicker", selection: $isOpen) {
Text("Open").tag(true)
Text("Closed").tag(false)
}
.pickerStyle(.segmented)
if isOpen {
Text("Top")
Text("Middle")
Text("Bottom")
}
}
}
}
CodePudding user response:
Try with .opacity
instead, so that your VStack
saves spaces in advance without messing up your layouts later. Code is below the image:
struct ContentView: View {
@State var isOpen: Bool = false
var body: some View {
container
}
@ViewBuilder var container: some View {
VStack {
header
content
}
.frame(width: 300, height: 110)
.background(.gray)
.cornerRadius(20)
}
@ViewBuilder var header: some View {
RoundedRectangle(cornerRadius: 5)
.frame(width: 50, height: 10)
.padding(.top)
}
@ViewBuilder var content: some View {
VStack(alignment: .leading) {
Picker("mypicker", selection: $isOpen) {
Text("Open").tag(true)
Text("Closed").tag(false)
}
.pickerStyle(.segmented)
Group {
Text("Top")
Text("Middle")
Text("Bottom")
}
.opacity(isOpen ? 1 : 0) //here
}
}
}
CodePudding user response:
In this case I would separate layout of header and content (assuming requirement that header should be visible always) independently of what's really in header or content
It can be done using free space consumer (like Color) and overlay
@ViewBuilder var container: some View {
VStack {
header
Color.clear
.overlay(content) // << here !!
}
.frame(width: 300, height: 110, alignment: .top)
.background(.gray)
.cornerRadius(20)
}
Tested with Xcode 13.4 / iOS 15.5
CodePudding user response:
Well, when my container's size is smaller than its content, I will think about using a ScrollView. It guarantees user can see everything.
@ViewBuilder var container: some View {
ScrollView {
VStack {
header
content
}.pading()
}
.frame(width: 300, height: 110)
.background(.gray)
.cornerRadius(20)
}