Just quickly here is the code how I finally used it. It is based @joosttk approach, but using preference to be changed at any time. Also I added a stroke so it is obvious why the ScrollView should shrink, too.
struct HeightPreferenceKey: PreferenceKey {
typealias Value = CGFloat
static var defaultValue: CGFloat = 40
static func reduce(value: inout CGFloat, nextValue: () -> CGFloat) {
value = nextValue()
}
}
struct FittedScrollView: View {
static func newString() -> String { String(repeating: "Hello World! ", count: Int.random(in: 1..<35)) }
@State private var contentString = Self.newString()
@State private var contentHeight: CGFloat = 40
var body: some View {
VStack {
ScrollView {
Text(contentString)
.padding(20)
.overlay(
GeometryReader { geo in
Color.clear.preference(key: HeightPreferenceKey.self, value: geo.size.height)
})
}
.frame(maxWidth: 300, maxHeight: contentHeight, alignment: .center)
.padding(20)
.background(RoundedRectangle(cornerRadius: 20).stroke(Color(white: 0.4), lineWidth: 3))
.background(RoundedRectangle(cornerRadius: 20).fill(Color(white: 0.8)))
Button("Next Text", action: { contentString = Self.newString() })
}
.frame(height: 300)
.onPreferenceChange(HeightPreferenceKey.self) {
contentHeight = $0
}
}
}
Topic:
UI Frameworks
SubTopic:
SwiftUI
Tags: