Currently I have a view like this:
struct StatsView: View {
var body: some View {
ScrollView {
Text("Test1")
Text("Test2")
Text("Test3")
}
}
}
This renders a view that contains 3 texts inside a scroll view. Whenever I drag any of these texts inside of the window, the view will move because it's scrollable, even if these 3 texts fit in the window and there is remaining space.
What I want to achieve is to only make the ScrollView
scrollable if its content exceeds the window's height. If not, I want the view to be static and not move.
I've tried to use GeometryReader
and setting the scroll view's frame to the window width and height, also the same for the content but I continue to have the same behavior. I have also tried setting minHeight
and maxHeight
without any luck.
Here is a possible approach if a content of scroll view does not require user interaction (as in PO question):
Tested with Xcode 11.4 / iOS 13.4
struct StatsView: View {
@State private var fitInScreen = false
var body: some View {
GeometryReader { gp in
ScrollView {
VStack { // container to calculate total height
Text("Test1")
Text("Test2")
Text("Test3")
//ForEach(0..<50) { _ in Text("Test") } // uncomment for test
}
.background(GeometryReader {
// calculate height by consumed background and store in
// view preference
Color.clear.preference(key: ViewHeightKey.self,
value: $0.frame(in: .local).size.height) })
}
.onPreferenceChange(ViewHeightKey.self) {
self.fitInScreen = $0 < gp.size.height // << here !!
}
.disabled(self.fitInScreen) // for iOS <16
//.scrollDisabled(self.fitInScreen) // for iOS 16+
}
}
}
Note: ViewHeightKey
preference key is taken from this my solution