5

我正在尝试为我的 imageView(下面代码中的 maskPreview)创建移动功能,以便用户可以在屏幕周围移动包含在 maskPreview 中的图片。这是我的触摸开始和触摸移动的代码:

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
if ([touches count]==1) {
    UITouch *touch= [touches anyObject];
    originalOrigin = [touch locationInView:maskPreview];
}
}
-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
if ([touches count]==1) {
    UITouch *touch = [touches anyObject];
    CGPoint lastTouch = [touch previousLocationInView:self.view];
    CGFloat movedDistanceX = originalOrigin.x-lastTouch.x;
    CGFloat movedDistanceY = originalOrigin.y-lastTouch.y;
    [maskPreview setFrame:CGRectMake(maskPreview.frame.origin.x+movedDistanceX, maskPreview.frame.origin.y + movedDistanceY, maskPreview.frame.size.width, maskPreview.frame.size.height)];
}
}

但我从应用程序中得到了一些奇怪的响应。我没有限制 imageview 可以移动多远,即防止它离开屏幕,但即使是一个小动作,我的 imageview 也会变得疯狂并消失。

非常感谢您的所有帮助

4

2 回答 2

9

在这个现代世界中,实施touchesBegan等方式太过分了。你只是把自己搞糊涂了,你的代码很快就会变得无法理解或维护。使用 UIPanGestureRecognizer;这就是它的用途。使用 UIPanGestureRecognizer 使视图可拖动是微不足道的。这是 UIPanGestureRecognizer 的动作处理程序,它使视图可拖动:

- (void) dragging: (UIPanGestureRecognizer*) p {
    UIView* vv = p.view;
    if (p.state == UIGestureRecognizerStateBegan ||
        p.state == UIGestureRecognizerStateChanged) {
        CGPoint delta = [p translationInView: vv.superview];
        CGPoint c = vv.center;
        c.x += delta.x; c.y += delta.y;
        vv.center = c;
        [p setTranslation: CGPointZero inView: vv.superview];
    }
}
于 2012-02-03T03:59:20.793 回答
2

您的代码有两个问题。首先,这一行是错误的:

CGPoint lastTouch = [touch previousLocationInView:self.view];

应该是这样的:

CGPoint lastTouch = [touch previousLocationInView:maskPreview];

真的,你甚至不应该使用previousLocationInView:. 你应该locationInView:像这样使用:

CGPoint lastTouch = [touch locationInView:maskPreview];

其次,你得到了movedDistanceX错误的迹象movedDistanceY。将它们更改为:

CGFloat movedDistanceX = lastTouch.x - originalOrigin.x;
CGFloat movedDistanceY = lastTouch.y - originalOrigin.y;

此外,文档是touchesBegan:withEvent:这样说的:

如果您在不调用的情况下覆盖此方法super(一种常见的使用模式),那么您还必须覆盖用于处理触摸事件的其他方法,如果只是作为存根(empy)实现。

因此,请确保您还覆盖了touchesEnded:withEvent:and touchesCancelled:withEvent:

无论如何,您可以更简单地执行此操作。一种方法是使用touchesBegan:withEvent:and和更新而不是. 您甚至不需要实例变量:touchesMoved:withEvent:previousLocationInView:locationInView:maskPreview.centermaskPreview.frameoriginalOrigin

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
}

-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
    if ([touches count]==1) {
        UITouch *touch = [touches anyObject];
        CGPoint p0 = [touch previousLocationInView:maskPreview];
        CGPoint p1 = [touch locationInView:maskPreview];
        CGPoint center = maskPreview.center;
        center.x += p1.x - p0.x;
        center.y += p1.y - p0.y;
        maskPreview.center = center;
    }
}

另一种方法是使用UIPanGestureRecognizer. 我把它留给读者作为练习。

于 2012-02-03T04:06:45.563 回答