旋转手势产生不希望的旋转 [英] Rotation gesture produces undesired rotation

查看:24
本文介绍了旋转手势产生不希望的旋转的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要仅使用一个手指运动来旋转用户运动的 UIImageview.为此,我使用旋转手势,然后使用以下代码覆盖 touchesMoved:

I need to rotate an UIImageview on user's motion using just one finger motion. For that I use a rotation gesture and then override touchesMoved with this code:

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

    let touch = touches.first
    if touch!.view === rotateImageView {
        let position = touch!.locationInView(self.view)

        let target = rotateImageView.center
        let angle = atan2(target.y-position.y, target.x-position.x)
        rotateImageView.transform = CGAffineTransformMakeRotation(angle)
    }
  }

只要用户停下来触摸屏幕并在屏幕的另一部分进行动作,这就会起作用.在那种情况下,当用户开始移动手指时,UIImageview 会在不希望的位置上旋转.我需要保持 UIImageview 的原始旋转位置以避免这种情况,但我不知道该怎么做.

This works as long as the user stop to touch the screen and make the motion on another part of the screen. On that scenario the UIImageview rotates on undesired position when the user starts to move the finger. I need to keep the original rotation position of the UIImageview to avoid this but I have no idea how to do it.

这个 gif 显示了我拥有的项目原型的当前行为.正如你所看到的,当我开始在右侧旋转时,火焰图标突然出现在触摸点附近,这就是我想要防止的.

This gif shows the current behavior on the project prototype I have. As you can see when I start to rotate on the right side the flame icon suddenly appears near the touch point, that's what I want to prevent.

2016 年 8 月 23 日更新

我使用了 Matt 和 Dasem 建议使用 CGAffineTransformRotate,但我仍然看到了跳跃.我采用 Dasem 代码并按如下方式适应我的项目(如果适应错误,请告诉我):

I used Matt and Dasem suggestion of using CGAffineTransformRotate but I still see the jump. I took Dasem code and adapted to my project like follows (Let me know if the adaption is wrong):

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

    origin = (touches.first?.locationInView(self.view))!

    //save the current transform
    tempTransform = rotateImageView.transform

}

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

    let touchPoint = touches.first?.locationInView(self.view)

    xOffSet = CGVector(dx:(origin.x)-rotateImageView.center.x, dy:(origin.x) - rotateImageView.center.y)
    yOffSet = CGVector(dx:touchPoint!.x - rotateImageView.center.x, dy:touchPoint!.y - rotateImageView.center.y)

    let angle = atan2(yOffSet.dy,yOffSet.dx) - atan2(xOffSet.dy,xOffSet.dx)
    rotateImageView.transform = CGAffineTransformRotate(tempTransform, angle)

}

当用户触摸触摸屏的不同区域时,此更改会产生类似的效果.在这个 gif 中,我更改了图像并删除了图标以使效果更加明显.

This change produces a similar effect when user touches a different region of the touchscreen. In this gif I've changed the image and remove the icons to make the effect more noticeable.

更新解决方案

使用 Jasem 更新重新应用代码并运行,以下代码在不使用子类化的情况下解决了问题

Reapplied code with Jasem update and it worked , the following code solved the problem without using subclassing

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

    origin = (touches.first?.locationInView(self.view))!
    xOffSet = CGVector(dx:(origin.x)-rotateImageView.center.x, dy:(origin.y) - rotateImageView.center.y)
    startingAngle = atan2(xOffSet.dy,xOffSet.dx)

    //save the current transform
    tempTransform = rotateImageView.transform
}

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

    let touchPoint = touches.first?.locationInView(self.view)
    yOffSet = CGVector(dx:touchPoint!.x - rotateImageView.center.x, dy:touchPoint!.y - rotateImageView.center.y)
    let angle = atan2(yOffSet.dy,yOffSet.dx)

    let deltaAngle = angle - startingAngle!
    rotateImageView.transform = CGAffineTransformRotate(tempTransform, deltaAngle)
}

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

//reset in case drag is cancelled
override func touchesCancelled(touches: Set<UITouch>?, withEvent event: UIEvent?) {
    rotateImageView.transform = tempTransform
    startingAngle = nil
}

推荐答案

你可能想把self.superview改成self.view(我的是子类)

you may want to change self.superview to self.view (mine is subclass)

var xOffSet:CGVector = CGVectorMake(0, 0)
var yOffSet:CGVector = CGVectorMake(0, 0)
var origin:CGPoint = CGPointZero
var tempTransform=CGAffineTransform()
var startingAngle:CGFloat?


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

    origin = (touches.first?.locationInView(self.superview))!
    xOffSet = CGVector(dx:(origin.x)-self.center.x, dy:(origin.y) - self.center.y)
    startingAngle = atan2(xOffSet.dy,xOffSet.dx)

    //save the current transform
    tempTransform = self.transform
}

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

    let touchPoint = touches.first?.locationInView(self.superview)
    yOffSet = CGVector(dx:touchPoint!.x - self.center.x, dy:touchPoint!.y - self.center.y)
    let angle = atan2(yOffSet.dy,yOffSet.dx)

    let deltaAngle = angle - startingAngle!
    self.transform = CGAffineTransformRotate(tempTransform, deltaAngle) 
}


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

//reset in case drag is cancelled
override func touchesCancelled(touches: Set<UITouch>?, withEvent event: UIEvent?) {
        self.transform = tempTransform
        startingAngle = nil
    }

这篇关于旋转手势产生不希望的旋转的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆