【问题标题】:LongPress on UIIImageView, create a clone "ghost" image, then drag it around长按 UIImageView,创建一个克隆的“幽灵”图像,然后拖动它
【发布时间】:2012-08-30 03:40:38
【问题描述】:

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

例如,要交换图像,用户可以这样做:

  1. 点击并按住左侧的 UIImageView
  2. 一个克隆的、较小的“幽灵”图像将出现在触摸坐标处
  3. 用户将克隆出来的图片拖到右边的UIImageView中
  4. 用户将手指从屏幕上松开以“放下”克隆的图像
  5. 然后左右 UIImageViews 可以淹没他们的图像。

这里有一些图片来说明:

原始状态:

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);

    }
}

【问题讨论】:

    标签: iphone uigesturerecognizer


    【解决方案1】:

    这可能是因为在创建图像(以及手势识别器)之前已经检测到触摸。我建议事先创建重影图像,但将它们隐藏起来。这样一来,手势识别器实际上会被触发,因为幻影图像已经存在。

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

    【讨论】:

    • 谢谢,但如果触摸位置不在隐藏的幽灵图像视图上,我不确定如何平移它们?
    • 他们为什么不在隐藏的图像视图上?
    • 啊,你的意思是创建与左/右 UIImageView 相同帧大小的隐藏图像视图吗?然后在取消隐藏时,将框架重新调整为正确的较小尺寸?
    • 我可能是错的,但似乎隐藏视图(或 alpha 0)不响应手势。啊,是的,刚刚检查了 Apple 文档:“隐藏的视图从其窗口中消失,并且不接收输入事件。” :(
    • 好的,那你不隐藏的 1x1 透明图像怎么样?
    【解决方案2】:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-04-01
      • 2021-11-22
      • 2016-07-12
      • 1970-01-01
      • 1970-01-01
      • 2018-01-24
      • 2011-12-30
      • 1970-01-01
      相关资源
      最近更新 更多