Created
March 4, 2023 12:17
-
-
Save LucasAbijmil/b95c7c49c05b6af59e077caf0f621a2e to your computer and use it in GitHub Desktop.
LazyScrollView – Before iOS 16.4 otherwise use the `scrollBounceBehavior` modifier
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
struct LazyScrollView<Content: View>: View { | |
@State private var fitsVertically = false | |
@State private var fitsHorizontally = false | |
private let content: Content | |
private let axes: Axis.Set | |
private let showsIndicators: Bool | |
private var activeScrollingDirections: Axis.Set { | |
return axes.intersection((fitsVertically ? [] : Axis.Set.vertical).union(fitsHorizontally ? [] : Axis.Set.horizontal)) | |
} | |
init(_ axes: Axis.Set = .vertical, showsIndicators: Bool = true, @ViewBuilder content: () -> Content) { | |
self.axes = axes | |
self.showsIndicators = showsIndicators | |
self.content = content() | |
} | |
var body: some View { | |
GeometryReader { geometryReader in | |
ScrollView(activeScrollingDirections, showsIndicators: showsIndicators) { | |
content | |
.background { | |
GeometryReader { | |
Color.clear.preference(key: ViewSizeKey.self, value: $0.frame(in: .local).size) | |
} | |
} | |
} | |
.onPreferenceChange(ViewSizeKey.self) { | |
fitsVertically = $0.height <= geometryReader.size.height | |
fitsHorizontally = $0.width <= geometryReader.size.width | |
} | |
} | |
} | |
} | |
private struct ViewSizeKey: PreferenceKey { | |
static var defaultValue: CGSize { | |
return .zero | |
} | |
static func reduce(value: inout Value, nextValue: () -> Value) { | |
let next = nextValue() | |
value = CGSize(width: value.width + next.width, height: value.height + next.height) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment