CizooDev CizooDev - 1 month ago 9
Swift Question

UIPanGestureRecognizer get the length between start and stop

This is my code :

override func viewDidLoad() {
super.viewDidLoad()
let panRecognizer = UIPanGestureRecognizer(target: self, action: #selector(PreviewViewController.respondsToPenGesture))
self.view.addGestureRecognizer(panRecognizer)}


Here blow is the respondsToPenGesture Func:

func respondsToPenGesture(sender: UIPanGestureRecognizer) {
let startLocation : CGPoint
if (sender.state == UIGestureRecognizerState.Began) {
startLocation = sender.locationInView(self.newEffectView)
}
else if (sender.state == UIGestureRecognizerState.Ended) {

let stopLocation = sender.locationInView(self.newEffectView)

let dx = stopLocation.x - startLocation.x;
let dy = stopLocation.y - startLocation.y;
let distance = sqrt(dx*dx + dy*dy );
NSLog("Distance: %f", distance);

}
}


I want to use this length,and it shows error : Constant 'startLocation' used before being initialized.

And if I change it to :

func respondsToPenGesture(sender: UIPanGestureRecognizer) {
//let startLocation : CGPoint
if (sender.state == UIGestureRecognizerState.Began) {
let startLocation = sender.locationInView(self.newEffectView)
}
else if (sender.state == UIGestureRecognizerState.Ended) {

let stopLocation = sender.locationInView(self.newEffectView)

let dx = stopLocation.x - startLocation.x;
let dy = stopLocation.y - startLocation.y;
let distance = sqrt(dx*dx + dy*dy );
NSLog("Distance: %f", distance);
}
}


It will show : Use of unresolved identifier 'startLocation'.
(P.s: i already tried with use switch and case , it shows the same problem)
Someone can help me with this problem ?
Thx in advance .

Answer

The problem is that handlePanRecognizer() is called every time the gesture is updated, so when the gesture ends, you don't have the startLocation because it was set in another call of the handler method.

You should store last location as an optional property:

var startPanLocation: CGPoint?

Now set it in .began case and use it to calculate the distance in .ended case:

func handlePanRecognizer(panRecognizer: UIPanGestureRecognizer) {
    let currentLocation = panRecognizer.location(in: self.newEffectView)

    switch panRecognizer.state {
    case .began:
        startPanLocation = currentLocation
    case .ended:
        let dx = currentLocation.x - startPanLocation.x;
        let dy = currentLocation.y - startPanLocation.y;
        let distance = sqrt(dx*dx + dy*dy );
        startPanLocation = nil
    default: break
    }
}

Btw, you cannot use the variable if it was defined but not initialized:

let startLocation : CGPoint      //defined
let startLocation = CGPoint.zero //initialized
Comments