Reputation: 81
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 .
Upvotes: 1
Views: 1296
Reputation: 7741
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
Upvotes: 3
Reputation: 1509
Three issues here.
Firstly, let
is used to define a const
variable, or one that will not change once it is created. Your first bit of code fails because you are attempting to change the value of startLocation
after it is created as an empty CGPoint
, if you change that let
into a var
, you should be fine.
Secondly, the next block of code has an issue with scoping. Anytime you use { }
, you create a new scope which has access to all the variables outside of the scope, and can create new variables within. Once that scope ends with the closing brace, everything that is created inside is destroyed, including your let startLocation
, which is why the else if
scope can't see it.
Finally, the scoping issue also applies to this function as a whole, every time the respondsToPanGesture(sender:)
method is called, a brand new startLocation
will be created, and all previous instances of it will be destroyed. If you want to maintain this value between calls, you'll need to create startLocation
in the class itself, and update it within the function.
class MyClass
{
var startLocation = CGPoint.zero
func respondsToPenGesture(sender: UIPanGestureRecognizer)
{
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);
}
}
}
Hope that helps :-)
Upvotes: 2