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

FloatingPanel is hard to dismiss if isRemovalInteractionEnabled is enabled #389

Closed
aclassen opened this issue Oct 7, 2020 · 6 comments · Fixed by #395
Closed

FloatingPanel is hard to dismiss if isRemovalInteractionEnabled is enabled #389

aclassen opened this issue Oct 7, 2020 · 6 comments · Fixed by #395

Comments

@aclassen
Copy link

aclassen commented Oct 7, 2020

Description

If isRemovalInteractionEnabled enabled, the panel is actually "hard" to dismiss compared to panel v1.
In v1 the panel was also dismissed if it was dragged no near bottom.
In v2 the panel is only dismissed if the panel is dragged with a very high velocity.

Expected behavior

The panel is easier to dismiss if isRemovalInteractionEnabled is enabled.

Actual behavior

Steps to reproduce

Open a example app panel where isRemovalInteractionEnabled is enabled.
Code example that reproduces the issue

How do you display panel(s)?

  • Add as child view controllers

How many panels do you displays?

  • 1

Environment

Library version
2.0.0
Installation method

  • CocoaPods

iOS version(s)
14.0

Xcode version
Version 12.0.1 (12A7300)

@scenee
Copy link
Owner

scenee commented Oct 12, 2020

@aclassen Thank you for your feedback. You can make it easy to remove a panel using floatingPanel(_:shouldRemoveAt location:with) delegate method which is called [here].(https://github.com/SCENEE/FloatingPanel/blob/master/Sources/Core.swift#L717).

But now I'm thinking the API should be reconsidered because the logic, which the velocity vector is calculated from a distance to a point of the hidden state and the pan gesture's velocity, is not appropriate for a gesture. So I have an idea that the core will use just a velocity of the panel pan gesture to determine whether a pane is removed or not, and then the delegate method will pass it to the argument.

@tnmendes
Copy link

I was able to do a workaround and now is working nicely.
@aclassen you just need to add state "tip" and when you are going to that step he will automatically dismiss

    func floatingPanelWillBeginAttracting(_ fpc: FloatingPanelController, to state: FloatingPanelState) {
                
        if state == FloatingPanelState.tip {
            fpc.dismiss(animated: true, completion: nil)
        }
    }
class MyFloatingPanelLayout: FloatingPanelLayout {
    let position: FloatingPanelPosition = .bottom
    let initialState: FloatingPanelState = .half
    var anchors: [FloatingPanelState: FloatingPanelLayoutAnchoring] {
        return [
            .full: FloatingPanelLayoutAnchor(absoluteInset: 60.0, edge: .top, referenceGuide: .safeArea),
            .half: FloatingPanelLayoutAnchor(fractionalInset: 0.5, edge: .bottom, referenceGuide: .safeArea),
            .tip: FloatingPanelLayoutAnchor(fractionalInset: 0.25, edge: .bottom, referenceGuide: .safeArea),
        ]
    }
    func backdropAlpha(for state: FloatingPanelState) -> CGFloat {
        return 0.5
    }
}

@sipersso
Copy link

@scenee I also find it very hard to remove the panel after upgrading to 2.0.0 today. Do you have an example of how to use the "ShouldRemoveAt" method to determine if the panel should be removed or not? I am not sure how to use location and velocity to calculate if the shouldRemoveAt method should return true or false here.

@scenee
Copy link
Owner

scenee commented Oct 15, 2020

@sipersso
Here is an example to ease removing a panel in 'shoudlRemoveAt' delegate method.

    func floatingPanel(_ fpc: FloatingPanelController, shouldRemoveAt location: CGPoint, with velocity: CGVector) -> Bool {
        let threshold: CGFloat = 5.0
        switch fpc.layout.position {
        case .top:
            return (velocity.dy <= -threshold)
        case .left:
            return (velocity.dx <= -threshold)
        case .bottom:
            return (velocity.dy >= threshold)
        case .right:
            return (velocity.dx >= threshold)
        }
    }

The default value of threshold is 10.0 in 2.0.0. It causes that it's hard to remove a panel. So I'm thinking it will be between 5.0 and 6.0.

@sipersso
Copy link

@scenee I just tried this with 5.0 and it works perfectly. Thank you!

scenee added a commit that referenced this issue Oct 17, 2020
Because the current threshold(10.0) makes it hard to remove a panel.

Resolve #389
@scenee
Copy link
Owner

scenee commented Oct 17, 2020

the velocity vector is calculated from a distance to a point of the hidden state and the pan gesture's velocity, is not appropriate for a gesture. So I have an idea that the core will use just a velocity of the panel pan gesture to determine whether a pane is removed or not, and then the delegate method will pass it to the argument.

After I tried the above new logic, I confirmed the current logic was better because a swipe speed to dismiss a panel and ease of the acceleration can change depending on a distance from a screen edge to hide it.

As a result, I'm going to ease a threshold to remove a panel in PR #395.

scenee added a commit that referenced this issue Oct 19, 2020
Because the current threshold(10.0) makes it hard to remove a panel.

Resolve #389
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

Successfully merging a pull request may close this issue.

4 participants