UIImage检测触摸和拖动

8
这是一个相当常见的问题,我有一些答案,但还差一点。我有一个按钮,按下它时会创建一张图片(代码如下)。
(numImages 在加载时设置为零,并用作创建的所有图像标记号的计数器)
UIImage *tmpImage = [[UIImage imageNamed:[NSString stringWithFormat:@"%i.png", sender.tag]] retain];
UIImageView *myImage = [[UIImageView alloc] initWithImage:tmpImage];

numImages += 1;

myImage.userInteractionEnabled = YES;
myImage.tag = numImages;
myImage.opaque = YES;
[self.view addSubview:myImage];
[myImage release];

接下来我有一个 touchesBegan 的方法,它将检测被触摸的内容。我需要它允许用户拖动新创建的图像。现在基本能够工作,但是当你拖动它时,图像会在屏幕上闪烁。我可以通过获取TAG来访问所点击的图像,但我无法使其平稳地被拖动。

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

    UITouch *touch = [[event allTouches] anyObject];
    CGPoint location = [touch locationInView:touch.view];

    if (touch.view.tag > 0) {
        touch.view.center = location;
    }

    NSLog(@"tag=%@", [NSString stringWithFormat:@"%i", touch.view.tag]);

}

- (void) touchesMoved:(NSSet *)touches withEvent: (UIEvent *)event {
    [self touchesBegan:touches withEvent:event];
}

它可以工作,当我点击每个图像时,我会得到每个图像的标签输出。但是当我拖动时,它会闪烁...有什么想法吗?

2个回答

34

回答自己的问题 - 我决定创建一个处理我放置在视图上的图像的类。

如果有人感兴趣,这是代码....

Draggable.h

#import <Foundation/Foundation.h>
@interface Draggable : UIImageView {
    CGPoint startLocation;
}
@end

可拖动的.m文件

#import "Draggable.h"
@implementation Draggable

- (void) touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event {
    // Retrieve the touch point
    CGPoint pt = [[touches anyObject] locationInView:self];
    startLocation = pt;
    [[self superview] bringSubviewToFront:self];
}
- (void) touchesMoved:(NSSet*)touches withEvent:(UIEvent*)event {
    // Move relative to the original touch point
    CGPoint pt = [[touches anyObject] locationInView:self];
    CGRect frame = [self frame];
    frame.origin.x += pt.x - startLocation.x;
    frame.origin.y += pt.y - startLocation.y;
    [self setFrame:frame];
}
@end

并且调用它

UIImage *tmpImage = [[UIImage imageNamed:"test.png"] retain];
UIImageView *imageView = [[UIImageView alloc] initWithImage:tmpImage];

CGRect cellRectangle;
cellRectangle = CGRectMake(0,0,tmpImage.size.width ,tmpImage.size.height );
UIImageView *dragger = [[Draggable alloc] initWithFrame:cellRectangle];
[dragger setImage:tmpImage];
[dragger setUserInteractionEnabled:YES];

[self.view addSubview:dragger];
[imageView release];
[tmpImage release];

谢谢您发布这个问题,但是我在执行时遇到了抖动效果,有什么方法可以避免吗? - itsaboutcode

1
通常当您更改center时会获得隐式动画。您是否在修改-contentMode或者调用了 -setNeedsDisplay呢?
您可以显式地请求动画,以避免删除和重新绘制:
if (touch.view.tag > 0) {
    [UIView beginAnimations:@"viewMove" context:touch.view];
    touch.view.center = location;
    [UIView commitAnimations];
}

请注意,NSLog() 可能非常缓慢(比您预期的要慢得多;它比简单的 printf 要复杂得多),这可能会在像 touchesMoved:withEvent: 这样经常调用的东西中引起问题。
顺便说一下,您正在泄漏 tmpImage

谢谢您的回复。我尝试了您建议的方法,但问题仍然存在。我认为这与我用来设置图像的代码有关?当我在Interface Builder中放置一个图像并将其设置为.h文件中的IBOutlet UIImageView时,它可以完美地移动。我在设置每个图像时是否漏掉了什么?(附言)感谢tmpImage提示-我错过了那个! - Matt Facer
我原以为这可能是标签的问题,但现在我认为可能是视图的问题。当我使用第一段代码放置图片时,它会到达0,0。每次我拖动它时,它似乎总是想要回到那里。所以这就导致了闪烁。当前位置,然后又回到那里...这让我发疯! - Matt Facer

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接