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.
Code Block Swiftstruct 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 |
} |
} |
} |