Home Using UIPanGestureRecognizer to swipe down UIView
Reply: 1

Using UIPanGestureRecognizer to swipe down UIView

RileyDev
1#
RileyDev Published in 2018-01-13 02:40:59Z

I have an IBAction for a UIPanGestureRecognizer in my UIView, I am able to handle the gesture and recognise the state changes from began, cancelled and ended, as well as respond to those changes.

However when using the sender.location to handle the swipe down, the UIView actually moves up once the gesture has began, and then continues to move down. The experience is jarring and I am not sure what I am doing wrong. Does anybody have any ideas ?

func update(_ translation: CGPoint, origin: CGPoint) {

    let offSetY = translation.y

    cardView.frame.origin.y = offSetY

    let multiplier = 1 - (translation.y / 2000)
    self.view.alpha = multiplier
}


func cancel(_ origin: CGPoint) {

    let animator = UIViewPropertyAnimator(duration: 0.6, dampingRatio: 0.6) {
        self.visualEffectView.alpha = 1
        self.cardView.alpha = 1.0
        self.view.alpha = 1.0
        self.cardView.center = origin
    }
    animator.startAnimation()
}

func finish() {
    let animator = UIViewPropertyAnimator(duration: 0.9, dampingRatio: 0.9) {
        self.visualEffectView.effect = nil
        self.dismiss(animated: true, completion: nil)
    }
    animator.startAnimation()
}



@IBAction func panGestureAction(_ sender: UIPanGestureRecognizer) {

    self.view.backgroundColor = .white
    let originalCardPosition = cardView.center

   //let cardOriginY = cardView.frame.origin.y
    let translation = sender.translation(in: self.cardView)
    let origin = sender.location(in: self.cardView)

        switch sender.state {
        case .changed:


            if translation.y > 0 { update(translation, origin: origin) }

        case .ended:

            let translation = sender.translation(in: self.cardView)

            if translation.y > 100 {

                finish()

            } else {
                cardView.alpha = 1.0
                cancel(originalCardPosition)

            }
        case .cancelled:
            cancel(originalCardPosition)

        default: break
        }

}
rmaddy
2#
rmaddy Reply to 2018-01-13 03:43:37Z

The problem is that you set the origin.y of the cardView directly to the value of translation.y. You need to add translation.y to the view's original y value determined when the gesture begins.

Add a property to the class:

var originalY: CGFloat = 0

Then in the .began state of the gesture, set it:

originalY = cardView.frame.origin.y

Then in your update method you set the origin:

cardView.frame.origin.y = originalY + offSetY
You need to login account before you can post.

About| Privacy statement| Terms of Service| Advertising| Contact us| Help| Sitemap|
Processed in 0.336683 second(s) , Gzip On .

© 2016 Powered by mzan.com design MATCHINFO