iOS:在UIImageView之间移动图像

iOS:在UIImageView之间移动图像,ios,Ios,我有一个视图控制器,其中有一个默认的UIview放置在整个屏幕上。我在这个视图中添加了几个UIImageView(比如说大约20个)。我想支持在这些UIImageView之间交换图像。我已经使用UIApgestureRecograiser来处理这些UIImageView上发生的触摸。我是否可以在此UIApgestureRecognitiser事件本身下处理这些UIImageView之间的图像拖放?(或)我是否需要使用UIPangestureRecognitor或触摸事件?在这些UIImageVi

我有一个视图控制器,其中有一个默认的UIview放置在整个屏幕上。我在这个视图中添加了几个UIImageView(比如说大约20个)。我想支持在这些UIImageView之间交换图像。我已经使用UIApgestureRecograiser来处理这些UIImageView上发生的触摸。我是否可以在此UIApgestureRecognitiser事件本身下处理这些UIImageView之间的图像拖放?(或)我是否需要使用UIPangestureRecognitor或触摸事件?在这些UIImageView之间实现图像拖放的最简单和最简单的方法是什么?请建议

谢谢大家!

一些想法

  • 您可以通过点击手势(例如,点击第一个图像视图,点击目标图像视图)实现这一点,但这不是很直观。使用
    UIPangestureRecognitor
    进行适当的拖放操作将使最终用户更加直观

  • 从技术上讲,您不是从图像视图中拖动图像,而是实际拖动图像视图本身。(如果没有图像视图,图像本身就没有视觉表现。)当您放开时,您将为图像视图帧的更改设置动画以完成幻觉


  • 如果您有一组
    图像视图
    ,您可以向它们的superview添加一个手势:

    @property (nonatomic, strong) NSMutableArray *imageViews;
    
    - (void)viewDidLoad
    {
        [super viewDidLoad];
    
        [self createImageViewArray];
    
        UIPanGestureRecognizer *gesture = [[UIPanGestureRecognizer alloc] initWithTarget:self
                                                                                  action:@selector(handlePan:)];
        [self.view addGestureRecognizer:gesture];
    }
    
    - (void)createImageViewArray
    {
        self.imageViews = [NSMutableArray array];
    
        // add your imageviews to the array any way you want
    
        ...
    }
    
    - (void)handlePan:(UIPanGestureRecognizer *)gesture
    {
        static UIImageView *draggedImage = nil;
        static CGRect draggedImageOriginalFrame;
    
        CGPoint location = [gesture locationInView:gesture.view];
    
        if (gesture.state == UIGestureRecognizerStateBegan)
        {
            // see if we grabbed an imageview
    
            draggedImage = [self determineImageForLocation:location];
    
            // if so, save its old location for future reference and bring it to the front
    
            if (draggedImage)
            {
                draggedImageOriginalFrame = draggedImage.frame;
                [draggedImage.superview bringSubviewToFront:draggedImage];
            }
        }
        else if (gesture.state == UIGestureRecognizerStateChanged && draggedImage != nil)
        {
            // if we're dragging it, then update its location 
    
            CGPoint translation = [gesture translationInView:gesture.view];
            CGRect frame = draggedImageOriginalFrame;
            frame.origin.x += translation.x;
            frame.origin.y += translation.y;
            draggedImage.frame = frame;
        }
        else if (draggedImage != nil && (gesture.state == UIGestureRecognizerStateEnded ||
                                         gesture.state == UIGestureRecognizerStateCancelled ||
                                         gesture.state == UIGestureRecognizerStateFailed))
        {
            // if we let go, let's see if we dropped it over another image view
    
            UIImageView *droppedOver = nil;
    
            if (gesture.state == UIGestureRecognizerStateEnded)
                droppedOver = [self draggedImageView:draggedImage toLocation:location];
    
            if (droppedOver == nil)
            {
                // fail; animate the restoring of the view back to it's original position
    
                [UIView animateWithDuration:0.25
                                 animations:^{
                                     draggedImage.frame = draggedImageOriginalFrame;
                                 }];
            }
            else
            {
                // succeed; make sure to bring the view we're about to animate to the front
    
                [droppedOver.superview bringSubviewToFront:droppedOver];
    
                // animate the swapping of the views
    
                [UIView animateWithDuration:0.25
                                 animations:^{
                                     draggedImage.frame = droppedOver.frame;
                                     droppedOver.frame = draggedImageOriginalFrame;
                                 }];
            }
        }
    }
    
    // see if we dragged an imageview over one of our imageviews, returning a point
    // to the image view we dropped it over
    
    - (UIImageView *)draggedImageView:(UIImageView *)draggedView toLocation:(CGPoint)location
    {
        for (UIImageView *imageview in self.imageViews)
            if (CGRectContainsPoint(imageview.frame, location) && imageview != draggedView)
                return imageview;
    
        return nil;
    }
    
    // see if we started the gesture over an imageview
    // (turns out that this is the same as "did we drag an image over another",
    // but as we're not dragging an image yet, just pass nil)
    
    - (UIImageView *)determineImageForLocation:(CGPoint)location
    {
        return [self draggedImageView:nil toLocation:location];
    }
    

    事实上,根本不要使用轻拍手势

    秘密在于使用imageView的superview

    你需要3个图像视图

    UIImageView *ImageViewA
    
    UIImageView *ImageViewB
    
    UIImageView *DraggableImageView
    
    假设您单击屏幕,主机视图得到一个ToucheSBegined事件。。。如果您拍摄ImageViewA并使用以下方法测试其rect:

    [rect containsPoint:touchPoint];
    
    如果这是真的,并且您已成功接触到第一个imageView。。。在触摸屏中开始拖动操作,如下所示:

    如果拍摄ImageViewA.superview,将获得视图的主体视图。。。然后,主机视图应接收以下命令:

    [newDraggableImageView setFrame:ImageViewA.frame];
    [newDraggableImageView setImage:ImageViewA.image];
    [hostView addSubview:newDraggableImageView];
    
    现在,您可以使用UIResponder方法TouchsBegain TouchsMoved和TouchsEnded跟踪主机视图上的触摸事件

    通过触摸移动:将移动坐标发送到新DragableImageView的框架中

    因为它在拖。。。其中一种方法是触摸式方法:

    如果图像帧位于第二个拖动点的帧内,则可以设置最终图像视图

    if ([frame containsRect:anotherFrame])
        ImageViewB.image = draggableImageView.image;
    
    抱歉,这是伪代码。。。希望您能理解逻辑流程…将图像添加到主机视图。。。或应用程序的窗口视图,并将其四处移动。。。一旦移动结束..测试imageView的位置并适当设置新的图像视图


    祝你好运!和快乐的编码

    罗布的回答非常好。我稍微修改了他的
    handlePan
    方法,允许对图像进行热交换

    - (void)handlePan:(UIPanGestureRecognizer *)gesture
    {
        static UIImageView *draggedImage = nil;
        static CGRect draggedImageLastFrame;
    
        CGPoint location = [gesture locationInView:gesture.view];
    
        if (gesture.state == UIGestureRecognizerStateBegan) {
    
            // see if we grabbed an imageview
    
            draggedImage = [self determineImageForLocation:location];
    
            // if so, save its old location for future reference and bring it to the front
    
            if (draggedImage) {
                draggedImageLastFrame = draggedImage.frame;
                [draggedImage.superview bringSubviewToFront:draggedImage];
                draggedImage.alpha = 0.6f;
            }
    
        } else if (gesture.state == UIGestureRecognizerStateChanged && draggedImage != nil) {
    
            // if we're dragging it, then update its horizontal location
    
            CGPoint translation = [gesture translationInView:gesture.view];
            CGRect frame = draggedImage.frame;
            frame.origin.x += translation.x;
            draggedImage.frame = frame;
            [gesture setTranslation:CGPointZero inView:gesture.view];
    
            UIImageView *draggedOver = [self draggedImageView:draggedImage toLocation:location];
            if (draggedOver != nil) {
    
                // animate the draggedOver image to the the draggedImage's last location
    
                [UIView animateWithDuration:0.25
                                 animations:^{
                                     CGRect currentFrame = draggedOver.frame;
                                     draggedOver.frame = draggedImageLastFrame;
                                     draggedImageLastFrame = currentFrame;
                                 }];
            }
    
        } else if (draggedImage != nil && (gesture.state == UIGestureRecognizerStateEnded ||
                                           gesture.state == UIGestureRecognizerStateCancelled ||
                                           gesture.state == UIGestureRecognizerStateFailed)) {
    
            // finished, animate the draggedImage into place
    
            [UIView animateWithDuration:0.25
                             animations:^{
                                 draggedImage.frame = draggedImageLastFrame;
                                 draggedImage.alpha = 1.0f;
                             }];
        }
    }
    


    好的,明白了!谢谢我还有一个疑问,在这种情况下,如何将两个ImageView移动(交换)到指定的交换位置。@Getsy参见示例代码。请注意,如果您在
    NSArray
    中获取图像视图,这类内容通常会得到简化,因此您可以快速枚举它们。