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 Swift| 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 |
| } |
| } |
| } |