'SwiftUI: ScrollView that drags bottom sheet with it
I'm trying to create a SwiftUI Scrollview that drags its container like this: https://drive.google.com/file/d/1O92DgsVI1OjM1HEUXUwVywB8gcdShOP-/view?usp=sharing
Many Apple apps use this (Apple Maps, Music, Wallet, etc) but I haven't found an easy way to do it wit SwiftUI. What do you think is the best way to implement this simply?
I've looked at most libraries here https://github.com/search?q=swiftui+drawer but none of them implements their drawer with a ScrollView in it that can drag the view.
I also tried implementing a custom UIScrollView as UIViewRepresentable and I tried to tweak the scrollViewWillBeginDragging() but I could not make it work.
Solution 1:[1]
Following is used to apply throughout the application
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
UIScrollView.appearance().bounces = false
}
Solution 2:[2]
Check the SheeKit library where that behaviour is supported for native sheets.
You can read about the implementation in this story on medium. Also, you can find the demo video in the end of the story.
In case if you need an advanced native SwiftUI scroll view with the support of content offset tracking and other UIKit-like configurability, check the SolidScroll library and the story behind it.
Solution 3:[3]
I've ran into the same issue and came across the FloatingPanel package. The repo includes an example to apply it to SwiftUI apps.
Solution 4:[4]
Ok, I ran into this problem while developing a drawer package myself, and I believe I was able to solve it using the legacy UIscrollView
and a UIViewRepresentable
wrapper.
if you want to use the packages you already had before, here's I ended up doing:
inside my Drawer, I've added this LegacyScrollView wrapper.
LegacyScrollView(.vertical, showsIndicators: showsIndicators) {
content
}
.onDragShouldBegin { pan, scrollView in
/// touch shouldn't begin when scrolling past zero content offset
scrollView.contentOffset.y - pan.translation(in: scrollView).y > 0
}
with this wrapper I'm able to access UIScrollView's gestureRecognizerShouldBegin(_:)
and override it through a SwiftUI modifier
Solution 5:[5]
struct ContentView: View {
init() {
UIScrollView.appearance().bounces = false
}
var body: some View {
ZStack {
DraggableView()
ScrollView {
LazyVStack {
Text("Hello World")
}
}
}
}
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | UditS |
Solution 2 | |
Solution 3 | guillaume |
Solution 4 | Bruno Fulber Wide |
Solution 5 | pkamb |