我正在构建一个iPhone应用程序。我有一个UIView包含一组UIImageView子类对象。用户可以通过触摸拖动和旋转图像视图。我在旋转后移动图像视图时遇到了问题。
要旋转图像视图,我应用变换旋转,它可以正常工作。它看起来像这样:
CGAffineTransform trans = self.transform;
self.transform = CGAffineTransformRotate(trans, delta);
当用户尝试通过触摸移动元素时,问题会出现。在touchesBegan:WithEvent:中,我将起始点保存在类变量startLocation中:
- (void) touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event
{
// Retrieve the touch point
CGPoint pt = [[touches anyObject] locationInView:self];
startLocation = pt;
}
在touchesMoved:withEvent:中,我有以下代码,如果图像视图上没有旋转变换,它就足够好了:
- (void) touchesMoved:(NSSet*)touches withEvent:(UIEvent*)event
{
CGPoint pt = [[touches anyObject] locationInView:self];
CGFloat dx = pt.x - startLocation.x;
CGFloat dy = pt.y - startLocation.y;
CGPoint newCenter = CGPointMake(self.center.x + dx, self.center.y + dy);
self.center = newCenter;
}
但是如果在图像视图上存在旋转变换,则图像视图会在每个touchesMoved事件上的屏幕上晃动并很快消失。在调试器中,我观察到pt的值变得怪异。在我看来,我需要改变这一点,我做了,就像这样:
- (void) touchesMoved:(NSSet*)touches withEvent:(UIEvent*)event
{
CGPoint pt = [[touches anyObject] locationInView:self];
if (!CGAffineTransformIsIdentity(self.transform)) {
pt = CGPointApplyAffineTransform(pt, self.transform);
}
CGFloat dx = pt.x - startLocation.x;
CGFloat dy = pt.y - startLocation.y;
CGPoint newCenter = CGPointMake(self.center.x + dx, self.center.y + dy);
}
这样做效果更好。我现在可以在屏幕上拖动图像。但是第一次移动会导致图像在一个方向或另一个方向上摇晃一次,具体取决于变换中的旋转角度和图像视图的尺寸。
如何在没有初始摇晃的情况下移动图像视图?
为什么我不需要转换startLocation(触摸开始时捕获的点)?
答案 0 :(得分:1)
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)_event {
CGPoint pt = [[touches anyObject] locationInView:self];
startLocation = pt;
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)_event {
CGPoint pt = [[touches anyObject] previousLocationInView:self];
CGFloat dx = pt.x - startLocation.x;
CGFloat dy = pt.y - startLocation.y;
CGPoint newCenter = CGPointMake(self.center.x + dx, self.center.y + dy);
self.center = newCenter;
}
- (void)setRotation:(float)rotation {
self.transform = CGAffineTransformRotate(self.transform, degreesToRadians(rotation));
}
答案 1 :(得分:0)
您似乎需要将主要未旋转对象的坐标转换为旋转视图系统。
看看UIView方法“convertPoint:toView:”:
convertPoint:toView:
将接收器坐标系中的点转换为指定视图的点。
- (CGPoint)convertPoint:(CGPoint)指向View:(UIView *)视图
参数
的点强> 的
接收器的本地坐标系(边界)中指定的点。
查看强> 的
要转换其坐标系点的视图。如果view为nil,则此方法将转换为窗口基坐标。否则,视图和接收者都必须属于同一个UIWindow对象。
返回值
转换为视图坐标系的点。
回应评论:
你必须得到手指触摸的“真实”坐标(在非旋转系统中),然后当手指移动时,你总是在主非旋转视图中有新的坐标:它们就是你的意思必须转换您正在移动的视图的旋转视图父级。
但你在屏幕上的 160,250 中看到它,
如果现在用户想要向右移动 +20 ,用户会在屏幕坐标中移动手指 +20 ,而不是 B 查看坐标, 所以用户希望在屏幕的 180,250 中看到它, 这意味着您需要在 B 坐标系中转换此点 ...
所以它更容易一些,你只需要在用户移动手指时获取手指的屏幕坐标,然后将其转换为旋转视图坐标( B )......