【问题标题】:Calculate rotation velocity and naturally rotate view iOS计算旋转速度并自然旋转视图iOS
【发布时间】:2016-07-21 22:32:11
【问题描述】:

我有一个圆形视图,并通过以下代码覆盖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
}

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

【问题讨论】:

  • 速度是距离除以时间,因此如果您在 touchesBegan 和 touchesEnd 中添加 NSDate().timesince1970,您可以计算开始事件和结束事件之间的秒数差异。距离只是 sqrt(dx^2 + dy^2)。或者这不是您正在寻找的速度?否则我会重写为下面的答案:)
  • 我只是想处理动态滚动以使其继续滚动。如果用户说滚动速度超快然后真的很慢然后放手,那么它将继续以比上次旋转速度更快的速度旋转。我在问题中强调了速度,但这完全是关于动态滚动

标签: ios swift transform trigonometry touch-event


【解决方案1】:

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

  • 方向(如果用户从左向右、向上或向下等移动)
  • 旋转(取决于 touchesBegan 和 touchesEnded 之间的时间的因素)
  • PI

这将创建一个 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)

}

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

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

在 touchesBegan 中我添加了:

self.touchPointStart = touchPoint

如上所述设置变量。

【讨论】:

  • 我不得不对其进行调整以使其适合我的情况,但谢谢!你得到了赏金!
  • 太棒了,我正在寻找一些东西,但你需要更新 swift 5 的答案
猜你喜欢
  • 2020-07-24
  • 2023-03-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-11-19
  • 2012-07-02
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多