Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Scroll Gesture Distinction #2

Open
maustinstar opened this issue Jul 15, 2020 · 6 comments
Open

Scroll Gesture Distinction #2

maustinstar opened this issue Jul 15, 2020 · 6 comments

Comments

@maustinstar
Copy link
Owner

Problem
When a ScrollView is embedded in the drawer, drags within the scroll view are used as scrolls and do not move the drawer. The current workaround is to have a larger "grabable" area at the top of the drawer.

Ideal Solution
When using the maps app, there is a velocity threshold. Drags below the threshold are interpreted as scrolls, while faster drags are used to move the drawer.

Suggested by u/ms4324

@maustinstar
Copy link
Owner Author

Edit

The maps app only scrolls when at the top height, and the drawer can only close when the scroll view is at the top.

@kylebeard56
Copy link

kylebeard56 commented Jul 16, 2020

Helpful tip: I made my own custom drawer a while ago and the trick to preventing internal scroll was to first track the rested height index when dragging occurs with the following update. For your code, simply add the snippet I've flagged with a comment:

    private var dragGesture: some Gesture {
        
        return DragGesture().onChanged({ (value) in
            
            self.height = min(-value.location.y + value.startLocation.y + self.restingHeight, self.fullHeight)
            self.animation = Animation?.none
            
        }).onEnded({ (value) in
            
            let change = value.startLocation.y - value.predictedEndLocation.y + self.restingHeight
            let first = self.heights.first!
            
            self.height = self.heights.reduce((first, abs(first - change))) { (current, value) -> (CGFloat, CGFloat) in
                
                let differential = abs(value - change)
                if current.1 > differential {
                    return (value, differential)
                }
                return current
            }.0
            
            // FIND THE INDEX HERE i.e. height[0] is bottom, height[1] is middle, height[2] is top
            if let index = self.heights.firstIndex(of: self.height) {
                // SET COMBINE VARIABLE HERE FOR ENABLE SCROLL IF INDEX = 2, DISABLE OTHERWISE
                self.heightIndex = index
            }
            
            self.restingHeight = self.height
            self.animation = Animation.spring()
            DispatchQueue.main.asyncAfter(deadline: .now() + self.animationDelay) {
              self.updateAppData()
            }
        })
    }

And then disable the ScrollView when the index isn't at the position you want it to enable scrolling via some @Binding

@maustinstar
Copy link
Owner Author

@kylebeard56 thanks for the snippet! I'll look into adding it in the next update.

Thanks for the support!

@antranapp
Copy link

do you already have any plan to have this in the next update?

@maustinstar
Copy link
Owner Author

@antranapp I haven't started working on this feature yet. I still have updates for the latest tag v0.0.4-beta which is focused on horizontal layouts. I plan on pushing those changes soon, and then looking into this.

I'm also thinking we can get better control of the underlying scroll view with the Introspect package https://github.com/siteline/SwiftUI-Introspect

@LinusGeffarth
Copy link

LinusGeffarth commented Aug 9, 2021

Hey there, any news on this one? Appreciate the library!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants