长按UIImageView,在拖动它时创建一个克隆“鬼”图像

时间:2012-08-30 03:40:38

标签: iphone uigesturerecognizer

我有一个示例项目,我试图测试这种行为。我有两个UIImageViews并排。我希望能够在左侧或右侧UIImageView上进行longPress,创建一个半透明的克隆图像,并将其拖动到另一个UIImageView以交换图像。

例如,要交换图像,用户可以执行以下操作:

  1. 点击并按住左侧的UIImageView
  2. 克隆的较小“鬼”图像将出现在触摸坐标
  3. 用户将克隆的图像拖到右侧的UIImageView
  4. 用户将从屏幕上释放手指以“删除”克隆的图像
  5. 然后左右UIImageViews可以淹没他们的图像。
  6. 以下是一些可说明的照片:

    原始状态:

    http://d.pr/i/PNVc

    长按左侧UIImageView并将较小的克隆图像添加为子视图:

    http://d.pr/i/jwxj

    我可以检测到长按并制作克隆图像,但除非我松开手指并在屏幕上再次触摸,否则我无法平移图像。

    我希望能够在一个动作中完成所有操作,而无需用户将手指从屏幕上移开。

    我不知道这是不是正确的做法,但这就是我现在正在做的事情。谢谢你的帮助!

    - (void)viewDidLoad
    {
        [super viewDidLoad];
        // Do any additional setup after loading the view, typically from a nib.
    
        [self addLongPressGestureToPiece:leftImageView];
        [self addLongPressGestureToPiece:rightImageView];
    }
    
    - (void)addLongPressGestureToPiece:(UIView *)piece
    {
        NSLog(@"addLongPressGestureToPiece");
        UILongPressGestureRecognizer *longPressGesture = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(longPressPiece:)];
        [longPressGesture setDelegate:self];
        [piece addGestureRecognizer:longPressGesture];
        [longPressGesture release];
    }
    
    - (void)addPanGestureRecognizerToPiece:(UIView *)piece
    {
        NSLog(@"addPanGestureRecognizerToPiece");
        UIPanGestureRecognizer *panGesture = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(panPiece:)];
        [panGesture setMaximumNumberOfTouches:1];
        [panGesture setDelegate:self];
        [piece addGestureRecognizer:panGesture];
        [panGesture release];
    }
    
    - (void)longPressPiece:(UILongPressGestureRecognizer *)gestureRecognizer
    {
        UIImageView *piece = (UIImageView*)[gestureRecognizer view];
    
        CGPoint point = [gestureRecognizer locationInView:self.view];
    
        if(gestureRecognizer.state == UIGestureRecognizerStateBegan)
        {
            NSLog(@"UIGestureRecognizerStateBegan");
    
            // create the semi-transparent imageview with the selected pic
    
            UIImage *longPressImage = [piece image];
            UIImageView *draggableImageView = [[UIImageView alloc] initWithFrame:CGRectMake(point.x - longPressImage.size.width/6/2, point.y - longPressImage.size.height/6/2, longPressImage.size.width/6, longPressImage.size.height/6)];
            draggableImageView.image = longPressImage;
            draggableImageView.alpha = 0.5;
            draggableImageView.userInteractionEnabled = YES;
            [self.view addSubview:draggableImageView];
    
            [self addPanGestureRecognizerToPiece:draggableImageView];
            photoView.userInteractionEnabled = NO;
        }
        else if(gestureRecognizer.state == UIGestureRecognizerStateChanged)
        {
            NSLog(@"Changed");
        }
        else if(gestureRecognizer.state == UIGestureRecognizerStateEnded)
        {
            NSLog(@"Ended");
            photoView.userInteractionEnabled = YES;
        }
    
    }
    
    
    - (void)adjustAnchorPointForGestureRecognizer:(UIGestureRecognizer *)gestureRecognizer
    {
        NSLog(@"adjustAnchorPointForGestureRecognizer");
        if (gestureRecognizer.state == UIGestureRecognizerStateBegan) {
            UIView *piece = gestureRecognizer.view;
            CGPoint locationInView = [gestureRecognizer locationInView:piece];
            CGPoint locationInSuperview = [gestureRecognizer locationInView:piece.superview];
            piece.layer.anchorPoint = CGPointMake(locationInView.x / piece.bounds.size.width, locationInView.y / piece.bounds.size.height);
            piece.center = locationInSuperview;
        }
    }
    
    - (void)panPiece:(UIPanGestureRecognizer *)gestureRecognizer
    {
        NSLog(@"pan piece");
        UIView *piece =[gestureRecognizer view];
    
        [self adjustAnchorPointForGestureRecognizer:gestureRecognizer];
    
        CGPoint translation = [gestureRecognizer translationInView:[piece superview]];
    
        // if velocity.y is positive, user is moving down, if negative, then moving up
        CGPoint velocity = [gestureRecognizer velocityInView:[piece superview]];
    
        if ([gestureRecognizer state] == UIGestureRecognizerStateBegan || [gestureRecognizer state] == UIGestureRecognizerStateChanged)
        {
            [piece setCenter:CGPointMake([piece center].x + translation.x, [piece center].y + translation.y)];
    
            [gestureRecognizer setTranslation:CGPointZero inView:[piece superview]];
        }
        else if([gestureRecognizer state] == UIGestureRecognizerStateEnded)
        {
            NSLog(@"piece y %f", piece.frame.origin.y);
    
        }
    }
    

2 个答案:

答案 0 :(得分:0)

这可能是因为在创建图像(因此手势识别器)之前已经检测到触摸。我建议事先创建鬼图像,但隐藏它们。这样,手势识别器实际上被解雇,因为鬼影已经存在。

如果您有很多图像,这可能很昂贵。如果性能不佳,您还可以考虑仅创建图像视图,但仅在触摸时为这些视图设置图像。这样您就不必不必要地将图像加载到内存中。

答案 1 :(得分:0)

对我来说,我发现由于.begin状态被多次调用longGestureAction,我得到了鬼影像。虽然我知道.changed会是连续的,但我发现(和文档证实)每个州都可以多次出现。因此,在.begin状态下,当你从GraphicsContext创建图像时,它会被多次调用打断 - 导致旧的幽灵。像我一样在你的代码中加一个警卫来防止这种情况发生。问题解决了。