UIPanGestureRecognizer获取开始和结束之间的长度

时间:2016-10-17 14:29:08

标签: ios swift position uipangesturerecognizer

这是我的代码:

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

这里打击是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);

    }   
}

我想使用这个长度,它显示错误:常量' startLocation'在初始化之前使用。

如果我将其更改为:

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);
    }
}

它将显示:使用未解析的标识符' startLocation'。 (P.s:我已经尝试过使用开关和外壳,它显示了同样的问题) 有人可以帮我解决这个问题吗? Thx提前。

2 个答案:

答案 0 :(得分:2)

这里有三个问题。

首先,let用于定义const变量,或者在创建后不会更改的变量。您的第一段代码失败是因为如果您将startLocation更改为CGPoint,那么在let创建为var后,您尝试更改{ }的值,你应该没事。

其次,下一个代码块存在范围问题。无论何时使用let startLocation,您都可以创建一个新范围,该范围可以访问范围之外的所有变量,并可以在其中创建新变量。一旦该范围以结束括号结束,内部创建的所有内容都将被销毁,包括else if,这就是respondsToPanGesture(sender:)范围无法看到的原因。

最后,范围界定问题也适用于整个函数,每次调用startLocation方法时,都会创建一个全新的startLocation,并且所有以前的实例都将被销毁。如果要在调用之间保持此值,则需要在类本身中创建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); } } } ,并在函数内更新它。

subroutine foo(a, b, c) bind(c)
   real, intent(in), optional :: a, b, c
   ...
end subroutine foo

希望有所帮助: - )

答案 1 :(得分:1)

问题是每次更新手势时都会调用handlePanRecognizer(),所以当手势结束时,你没有startLocation,因为它是在处理程序方法的另一个调用中设置的。

您应将最后一个位置存储为可选属性:

var startPanLocation: CGPoint?

现在将其设置为.began大小写并使用它来计算.ended案例中的距离:

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
    }
}

顺便说一下,如果变量已定义但未初始化,则无法使用该变量:

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