Skip to content

Instantly share code, notes, and snippets.

@manmal
Last active March 1, 2024 16:08
Show Gist options
  • Save manmal/72526fa76aec83572ea3ce065fd818e6 to your computer and use it in GitHub Desktop.
Save manmal/72526fa76aec83572ea3ce065fd818e6 to your computer and use it in GitHub Desktop.
Wrap a SwiftUI View in a ScrollView, expanding to full height/width & preventing bouncing when possible (iOS > = 16.4)
import SwiftUI
/// Wraps the content in a ScrollView that only bounces
/// if the content size exceeds the visible area;
/// and makes the content fill the ScrollView if desired.
/// Per default, the content fills the ScrollView only
/// vertically.
///
/// Usage:
///
/// ```
/// ScrollViewThatFits {
/// VStack {
/// // Your views here...
/// }
/// }
/// ```
/// Discussion here: https://x.com/manuelmaly/status/1763514873760137506?s=61
///
/// Heavily inspired by
/// https://x.com/alpennec/status/1762396898168656107?s=20
/// and
/// https://x.com/mecid/status/1762378791295254808?s=20
public struct ScrollViewThatFits<Content: View>: View {
var fillScrollView: Axis.Set
var edgesIgnoringSafeArea: Edge.Set
var content: () -> Content
public init(
edgesIgnoringSafeArea: Edge.Set = Edge.Set(),
fillScrollView: Axis.Set = .vertical,
@ViewBuilder content: @escaping () -> Content
) {
self.edgesIgnoringSafeArea = edgesIgnoringSafeArea
self.fillScrollView = fillScrollView
self.content = content
}
public var body: some View {
GeometryReader { proxy in
ScrollView {
content()
.frame(
minWidth: fillScrollView.contains(.horizontal) ? proxy.size.width : nil,
minHeight: fillScrollView.contains(.vertical) ? proxy.size.height : nil
)
}.scrollBounceBehavior(.basedOnSize)
}
.edgesIgnoringSafeArea(edgesIgnoringSafeArea)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment