s3rkan
s3rkan

Reputation: 31

UIPanGestureRecognizer is not working in iOS 13

We have developed an app in iOS 12 which worked really fine. Now in iOS 13 UIPanGestureRecognizer is not working any more.

I've search for solutions but didn't find anything.

@IBAction func handlePan(recognizer:UIPanGestureRecognizer) {
    let translation = recognizer.translation(in: self.view)
    if let view = recognizer.view {
        let center = view.frame.origin.y + view.bounds.height / 2
        if(center <= SliderView.bounds.height && center >= SliderView.bounds.minY) {
            view.center = CGPoint(x:view.center.x, y:view.center.y + translation.y)
        }

        if(center > SliderView.bounds.height) {
            view.center = CGPoint(x: view.center.x, y: view.center.y - 1)
        }

        if(center < SliderView.bounds.minY) {
            view.center = CGPoint(x: view.center.x, y: view.center.y + 1)
        }

        lowerSliderView.frame = CGRect(x: 0, y: center, width: SliderView.bounds.width, height: SliderView.bounds.height - center)

        slider = 1 - Float(center / SliderView.bounds.height)
        slider = min(slider, 1.0)
        slider = max(slider, 0.0)
    }
    recognizer.setTranslation(CGPoint.zero, in: self.view)
}

I expect that the slider will work on the app.

Upvotes: 3

Views: 2189

Answers (1)

FranticRock
FranticRock

Reputation: 3283

I had similar issues with my gesture recognizer on iOS13. (Worked fine on 12)

My problem was: I was setting .center = someValue, on my view which had the gesture recognizer on it, but that view also had Constraints on it. iOS13 doesn't seem to like it when you have constraints on a view, and are also setting it's frame manually. So i converted my code completely to just set the frame inside the gesture recognizer's handler method. iOS13 seems to have gotten more strict with preventing you from setting .center, or .frame manually if you also have constraints on that view and are calling layoutIfNeeded() causing a layout pass. I'm not sure about this, but for now, i'm back up and running using manual frame setting.

If your gesture recognizer event is not firing, please try to implement the following method and inspect the values inside to see if there are other gesture recognizers overlaid and competing for the touch gesture. Return TRUE for your gesture recognizer, and suppress others, or just return true for all of them. You need to set the delegate first.

func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer,
                       shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
    if (gestureRecognizer is UIPanGestureRecognizer || gestureRecognizer is UIRotationGestureRecognizer) {
        print("Should recognize")
        return true
    } else {
        print("Should NOT recognize")
        return false
    }
}

This is the setup of mine. works fine now, after I removed all the constraints from my view which had the recognizer on it. Constraints were "undoing" the translations which I had in the gesture recognizer method, only resulting in +1 or -1 movement of the view, and then it snapped back in place.

 let recStart = UIPanGestureRecognizer(target: self, action: #selector(handleStartPan))
    recStart.delegate = self
    self.startView.addGestureRecognizer(recStart)

And handleStartPan:

@objc final func handleStartPan(_ gestureRecognizer: UIPanGestureRecognizer) {
    if gestureRecognizer.state == .began || gestureRecognizer.state == .changed {

        let translation = gestureRecognizer.translation(in: containerOfMyView)
        // do stuff with translation.x or .y
    ... 

Upvotes: 4

Related Questions