如何通过触摸移动 UIImageView

发布于 2025-01-02 05:34:58 字数 934 浏览 0 评论 0原文

我正在尝试为我的 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)];
}
}

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

预先非常感谢您的所有帮助

I'm trying to create moving functionality to my imageView (maskPreview in the code below), so that users can move a picture, which is contained in maskPreview, around the screen. Here's my code for touch begin and touch moved:

-(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)];
}
}

but I'm getting some weird responses from the app. I haven't put restrictions on how far the imageview can move, i.e. to prevent it from going out of the screen, but even if it's a small move, my imageview goes wild and disappears.

Thanks alot in advance for all the help

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

为人所爱 2025-01-09 05:34:58

在这个现代世界中,实现 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];
    }
}

Implementing touchesBegan and so on is way overkill in this modern world. You're just confusing the heck out of yourself, and your code will quickly become impossible to understand or maintain. Use a UIPanGestureRecognizer; that's what it's for. Making a view draggable with a UIPanGestureRecognizer is trivial. Here's the action handler for a UIPanGestureRecognizer that makes the view draggable:

- (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];
    }
}
晚风撩人 2025-01-09 05:34:58

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

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

它应该是这样的:

CGPoint lastTouch = [touch previousLocationInView:maskPreview];

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

CGPoint lastTouch = [touch locationInView:maskPreview];

其次,您得到的 movedDistanceXmovedDistanceY 的符号是错误的。将它们更改为:

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

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

如果您在不调用 super(常见使用模式)的情况下重写此方法,则还必须重写用于处理触摸事件的其他方法(如果仅作为存根(空)实现)。

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

不管怎样,你可以更简单地做到这一点。一种方法是将 touchesBegan:withEvent: 设为空,并使用 previousLocationInView:完成 touchesMoved:withEvent: 中的所有工作locationInView:,并更新maskPreview.center而不是maskPreview.frame。您甚至不需要 originalOrigin 实例变量:

-(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。我把它留给读者作为练习。

There are two problems with your code. First, this line is wrong:

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

It should be this:

CGPoint lastTouch = [touch previousLocationInView:maskPreview];

Really, you shouldn't even be using previousLocationInView:. You should just be using locationInView: like this:

CGPoint lastTouch = [touch locationInView:maskPreview];

Second, you are getting the signs of movedDistanceX and movedDistanceY wrong. Change them to this:

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

Also, the documentation for touchesBegan:withEvent: says this:

If you override this method without calling super (a common use pattern), you must also override the other methods for handling touch events, if only as stub (empy) implementations.

So make sure you're also overriding touchesEnded:withEvent: and touchesCancelled:withEvent:.

Anyway, you can do this quite a bit more simply. One way is to make touchesBegan:withEvent: empty and do all the work in touchesMoved:withEvent: by using both previousLocationInView: and locationInView:, and updating maskPreview.center instead of maskPreview.frame. You won't even need the originalOrigin instance variable:

-(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;
    }
}

Another way to do this is by using a UIPanGestureRecognizer. I leave that as an exercise for the reader.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文