计算旋转速度并自然旋转视图iOS

时间:2023-02-09 10:02:43

I have a circle-shaped view and have it rotate via the following code overriding touchesBegan(touches:, withEvent:) and touchesMoved(touches:, withEvent:).

我有一个圆形的视图,并通过以下代码旋转覆盖touchesBegan(touches:,withEvent :)和touchesMoved(touches:,withEvent :)。

var deltaAngle = CGFloat(0)
var startTransform: CGAffineTransform?

override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?)
{
    let touchPoint = touches.first!.locationInView(view)

    let dx = touchPoint.x - view.center.x
    let dy = touchPoint.y - view.center.y

    deltaAngle = atan2(dy, dx)
    startTransform = arrowPickerView.transform
}

override func touchesMoved(touches: Set<UITouch>, withEvent event: UIEvent?)
{
    let touchPoint = touches.first!.locationInView(view)

    let dx = touchPoint.x - view.center.x
    let dy = touchPoint.y - view.center.y
    let angle = atan2(dy, dx)
    let angleDifference = deltaAngle - angle
    let transform = CGAffineTransformRotate(startTransform!, -angleDifference)
    arrowPickerView.transform = transform
}

I want to override touchesEnded(touches:, withEvent:) to calculate the velocity and have the view naturally rotate a little (similar to continuous scrolling). I currently save the original transform and calculate the delta angle. How can I implement this? Thanks in advance!

我想覆盖touchesEnded(touches:,withEvent :)来计算速度并让视图自然旋转一点(类似于连续滚动)。我目前保存原始变换并计算delta角度。我该如何实现呢?提前致谢!

1 个解决方案

#1


2  

In my example below, the CGAffineTransformRotate depends on:

在下面的示例中,CGAffineTransformRotate取决于:

  • direction (if the user moves from left to right, up or down etc)
  • 方向(如果用户从左向右移动,向上或向下移动等)
  • rotation (a factor dependent on the time between touchesBegan and touchesEnded)
  • 旋转(取决于touchesBegan和touchesEnded之间的时间因素)
  • PI
  • PI

This creates an CGAffineTransformRotate and this rotates with duration 1 (s), to create a feel of kinetic scrolling the UIViewAnimationOptions.CurveEaseOut property is used

这将创建一个CGAffineTransformRotate,并以1(s)的持续时间旋转,以创建动态滚动的感觉UIViewAnimationOptions.CurveEaseOut属性被使用

override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent?) {

    let touchPointEnd = touches.first!.locationInView(view)

    self.dateTouchesEnded = NSDate()

    let delay : NSTimeInterval = NSTimeInterval(0)

    let timeDelta : Double = self.dateTouchesEnded!.timeIntervalSince1970 - self.dateTouchesStarted!.timeIntervalSince1970

    let horizontalDistance : Double = Double(touchPointEnd.x - self.touchPointStart!.x)
    let verticalDistance : Double = Double(touchPointEnd.y - self.touchPointStart!.y)

    var direction : Double = 1
    if (fabs(horizontalDistance) > fabs(verticalDistance)) {
        if horizontalDistance > 0 {
            direction = -1
        }
    } else {
        if verticalDistance < 0 {
            direction = -1
        }
    }

    let rotation : Double = (0.1 / timeDelta < 0.99) ? 0.1 / timeDelta : 0.99

    let duration : NSTimeInterval = NSTimeInterval(1)
    UIView.animateWithDuration(duration, delay: delay, options: UIViewAnimationOptions.CurveEaseOut, animations: {
        let transform = CGAffineTransformRotate(self.imageView.transform, CGFloat(direction) * CGFloat(rotation) * CGFloat(M_PI))
        self.imageView.transform = transform
        }, completion: nil)

}

I added the variables to keep track of the start and end time of touches and added the CGPoint location of the touchesBegan function

我添加了变量来跟踪触摸的开始和结束时间,并添加了touchesBegan函数的CGPoint位置

var dateTouchesStarted : NSDate?
var dateTouchesEnded : NSDate?
var touchPointStart : CGPoint?

In touchesBegan i added:

在touchesBegan我添加:

self.touchPointStart = touchPoint

To set the variable as explained above.

如上所述设置变量。

#1


2  

In my example below, the CGAffineTransformRotate depends on:

在下面的示例中,CGAffineTransformRotate取决于:

  • direction (if the user moves from left to right, up or down etc)
  • 方向(如果用户从左向右移动,向上或向下移动等)
  • rotation (a factor dependent on the time between touchesBegan and touchesEnded)
  • 旋转(取决于touchesBegan和touchesEnded之间的时间因素)
  • PI
  • PI

This creates an CGAffineTransformRotate and this rotates with duration 1 (s), to create a feel of kinetic scrolling the UIViewAnimationOptions.CurveEaseOut property is used

这将创建一个CGAffineTransformRotate,并以1(s)的持续时间旋转,以创建动态滚动的感觉UIViewAnimationOptions.CurveEaseOut属性被使用

override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent?) {

    let touchPointEnd = touches.first!.locationInView(view)

    self.dateTouchesEnded = NSDate()

    let delay : NSTimeInterval = NSTimeInterval(0)

    let timeDelta : Double = self.dateTouchesEnded!.timeIntervalSince1970 - self.dateTouchesStarted!.timeIntervalSince1970

    let horizontalDistance : Double = Double(touchPointEnd.x - self.touchPointStart!.x)
    let verticalDistance : Double = Double(touchPointEnd.y - self.touchPointStart!.y)

    var direction : Double = 1
    if (fabs(horizontalDistance) > fabs(verticalDistance)) {
        if horizontalDistance > 0 {
            direction = -1
        }
    } else {
        if verticalDistance < 0 {
            direction = -1
        }
    }

    let rotation : Double = (0.1 / timeDelta < 0.99) ? 0.1 / timeDelta : 0.99

    let duration : NSTimeInterval = NSTimeInterval(1)
    UIView.animateWithDuration(duration, delay: delay, options: UIViewAnimationOptions.CurveEaseOut, animations: {
        let transform = CGAffineTransformRotate(self.imageView.transform, CGFloat(direction) * CGFloat(rotation) * CGFloat(M_PI))
        self.imageView.transform = transform
        }, completion: nil)

}

I added the variables to keep track of the start and end time of touches and added the CGPoint location of the touchesBegan function

我添加了变量来跟踪触摸的开始和结束时间,并添加了touchesBegan函数的CGPoint位置

var dateTouchesStarted : NSDate?
var dateTouchesEnded : NSDate?
var touchPointStart : CGPoint?

In touchesBegan i added:

在touchesBegan我添加:

self.touchPointStart = touchPoint

To set the variable as explained above.

如上所述设置变量。