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

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

问题描述

我需要仅使用一根手指运动就可以根据用户的运动旋转 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天全站免登陆