scenee / FloatingPanel

A clean and easy-to-use floating panel UI component for iOS
MIT License
5.59k stars 507 forks source link

Animation stutters #443

Open sadiq81 opened 3 years ago

sadiq81 commented 3 years ago

https://user-images.githubusercontent.com/1586725/109475175-ac92db80-7a75-11eb-8fa2-63302f2998c6.MP4

Description

When I'm dragging the panel from tip to half the animation stutters in the end

Expected behavior

Animation should be fluent

Actual behavior

Animation stutters/jumps

Steps to reproduce

Code example that reproduces the issue

extension PSSProductDetailViewController: FloatingPanelControllerDelegate, FloatingPanelLayout {

    var position: FloatingPanelPosition { .bottom }

    var initialState: FloatingPanelState { .tip }

    func backdropAlpha(for state: FloatingPanelState) -> CGFloat {
        return 0.7
    }

    var anchors: [FloatingPanelState: FloatingPanelLayoutAnchoring] {
        let padding = (self.panel?.surfaceView.grabberHandlePadding ?? 0)
        return [
            .full: FloatingPanelLayoutAnchor(absoluteInset: 15.0, edge: .top, referenceGuide: .safeArea),
            .half: FloatingPanelLayoutAnchor(absoluteInset: self.addProductView.frame.maxY + 34 + padding, edge: .bottom, referenceGuide: .superview),
            .tip: FloatingPanelLayoutAnchor(absoluteInset: 110.0, edge: .bottom, referenceGuide: .safeArea),

        ]
    }

    public func floatingPanelDidChangePosition(_ fpc: FloatingPanelController) {
        self.addMoreButton.isHidden = !(fpc.state == .tip)
        self.closeButton.isHidden = (fpc.state == .tip)
        self.productSubTitleLabel.text = (fpc.state == .tip) ? Strings.Localizable.shoppingAddedItem : self.productSubTitleLabel.accessibilityLabel
    }

    public func floatingPanelDidRemove(_ fpc: FloatingPanelController) {
        self.viewModel.rxScannedBarcode.onNext(nil)
    }

    public func floatingPanelDidMove(_ fpc: FloatingPanelController) {

        let currentY = fpc.surfaceLocation.y

        let tipY = fpc.surfaceLocation(for: .tip).y
        let halfY = fpc.surfaceLocation(for: .half).y

        let distanceToHalf = max(0, currentY - halfY)
        let totalDistance = tipY - halfY
        let percentage = (0.0...1.0).clamp((totalDistance - distanceToHalf) / totalDistance)

        self.updatePanelLayout(percentage: percentage)

        print("currentY: \(currentY) tipY: \(tipY) halfY: \(halfY) percentage: \(percentage)")
    }
}

fileprivate func updatePanelLayout(percentage: CGFloat) {

        let imageSize: CGFloat = 70 + (130 * percentage)
        let imageLeft: CGFloat = 20 + (((self.view.frame.width / 2) - (imageSize / 2)) * percentage)
        let labelTop: CGFloat = 20 + ((self.assortmentsStackView.frame.maxY) * percentage)
        let labelLeft: CGFloat = 90 - (90 * percentage) + 20

        self.imageSizeConstraint.constant = imageSize
        self.imageLeftConstraint.constant = imageLeft
        self.labelTopConstraint.constant = labelTop
        self.labelLeftConstraint.constant = labelLeft

        self.scrollContainerView.setNeedsLayout()
        self.scrollContainerView.layoutIfNeeded()
}

How do you display panel(s)?

How many panels do you displays?

Environment

Library version 2.1.0

Installation method

iOS version(s)

14.4

Xcode version

12.4

scenee commented 3 years ago

It seems that target positions for half state calculated from the following code before/after the animation are different. self.addProdctView and padding might affect the animation.

.half: FloatingPanelLayoutAnchor(absoluteInset: self.addProductView.frame.maxY + 34 + padding, edge: .bottom, referenceGuide: .superview)
kallipigous commented 2 years ago

I have the same problem. Animating around the half state seems to mmentarily jump to 50% before it goes to what I want it to be.

      .half: FloatingPanelLayoutAnchor(absoluteInset: 100, edge: .bottom, referenceGuide: .superview)

causes stuttering when animating around the half state.