I’m a bit stumped building a draggable slide containing a list. Inspired by this post, a MRE of what I have is below.
import SwiftUI
struct ContentView: View {
static let kMinHeight: CGFloat = 100.0
@State var currentHeight: CGFloat = kMinHeight // << any initial
var body: some View {
GeometryReader { g in // << for top container height limit
ZStack(alignment: .bottom) {
Rectangle().fill(Color.yellow) // << just for demo
self.card()
.gesture(DragGesture()
.onChanged { value in
// as card is at bottom the offset is reversed
let newHeight = self.currentHeight - (value.location.y - value.startLocation.y)
if newHeight > Self.kMinHeight && newHeight < g.size.height {
self.currentHeight = newHeight
}
})
}
}
}
func card() -> some View {
ZStack(alignment: .top){
RoundedRectangle(cornerRadius: 16.0)
.frame(height:currentHeight)
VStack{
RoundedRectangle(cornerRadius: Constants.radius)
.fill(Color.white)
.frame(
width: Constants.indicatorWidth,
height: Constants.indicatorHeight
)
Text("Card")
.font(.title)
.fontWeight(.bold)
.foregroundColor(Color.white)
.multilineTextAlignment(.center)
.padding(.top)
Text("LINE 2")
.foregroundColor(Color.white)
// Uncomment the following lines, and the slides becomes unusable
// List {
// Text("The Fellowship of the Ring")
// Text("The Two Towers")
// Text("The Return of the King")
//}
}
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
The slides built using this example works, but note that I’ve commented out a few lines containing a list. Once these lines are uncommented, the slider becomes unusable.
Two obvious questions: (1) Why is that, and (2) any suggestions on how to fix it? 🙂
2
Answers
The problem you are having is the
List
is a greedy view. It is taking up ALL of the space it possibly can, which throws your height out of whack. The simple solution is to put it in a frame, that is zero when the card is all the way down. Since we have those values, all we need to do is this:In your code you are only specifying the height of the rectangle within the card. This isn’t an issue if only the rectangle is present. But:
The trouble here is that
List
wraps its own scrolling behavior, so it expands to take up all the space it can. Rather than capping only the rectangle inside card, cap the height of your card tocurrentHeight
: