拖放对象并将其返回到原始位置

时间:2011-04-11 21:31:17

标签: iphone objective-c xcode drag-and-drop

我正在尝试拖动图像并让它在释放后返回原始位置。到目前为止,我可以使用以下代码将图像创建为按钮来拖动图像:(在此问题的答案中可以看到:Basic Drag and Drop in iOS

UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
[button addTarget:self action:@selector(imageTouch:withEvent:) forControlEvents:UIControlEventTouchDown];
[button addTarget:self action:@selector(imageMoved:withEvent:) forControlEvents:UIControlEventTouchDragInside];
[button setImage:[UIImage imageNamed:@"vehicle.png"] forState:UIControlStateNormal];
[self.view addSubview:button];

后来我定义:

- (IBAction) imageMoved:(id) sender withEvent:(UIEvent *) event
{
    CGPoint point = [[[event allTouches] anyObject] locationInView:self.view];
    UIControl *control = sender;
    control.center = point;
}

如何让它在释放后返回原位?对于初学者我将保存每个图像应该返回的位置,但是,无论如何,无论如何都指示UIImage从它的当前位置开始并转移到另一个?或任何其他替代解决方案?

5 个答案:

答案 0 :(得分:7)

Apple推荐UIGestureRecognizer用于最近的iOS。你不仅可以将它用于UIButton,还可以用于UIView(尤其是你的UIImageView)等等。所以我想推荐它。

在界面中:

@interface TestDragViewController : UIViewController {
    IBOutlet UIImageView *dragImage;
    CGPoint originalCenter;
}

在viewDidLoad中,plz记得启用userInteraction:

- (void)viewDidLoad {
    [super viewDidLoad];


    UIPanGestureRecognizer *panGesture = [[UIPanGestureRecognizer alloc] initWithTarget:self 
                                                                                 action:@selector(dragGesture:)];
    [dragImage addGestureRecognizer:panGesture];
    [dragImage setUserInteractionEnabled:YES];
}

在其选择器中,我只是将动画设置为可视化返回效果:

#pragma mark -
#pragma mark UIPanGestureRecognizer selector
- (void) dragGesture:(UIPanGestureRecognizer *) panGesture{
    CGPoint translation = [panGesture translationInView:self.view];

    switch (panGesture.state) {
        case UIGestureRecognizerStateBegan:{
            originalCenter = dragImage.center;
        }
            break;
        case UIGestureRecognizerStateChanged:{
            dragImage.center = CGPointMake(dragImage.center.x + translation.x,
                                           dragImage.center.y + translation.y);
        }
            break;
        case UIGestureRecognizerStateEnded:{            
            [UIView animateWithDuration:kImageReturnTime 
                             animations:^{
                                 dragImage.center = originalCenter;
                             }
                             completion:^(BOOL finished){
                                 NSLog(@"Returned");
                             }];
        }
            break;
        default:
            break;
    }

    [panGesture setTranslation:CGPointZero inView:self.view];
}

干杯,

托米

答案 1 :(得分:1)

在全球范围内或在.h文件中定义CGPoint。

  CGPoint point;          

      UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
      [button addTarget:self action:@selector(imageTouch:withEvent:)forControlEvents:UIControlEventTouchDown];
      [button addTarget:self action:@selector(imageMoved:withEvent:) forControlEvents:UIControlEventTouchDragInside];
      [button setImage:[UIImage imageNamed:@"vehicle.png"] forState:UIControlStateNormal];
      [self.view addSubview:button];

后来我定义:

- (IBAction) imageMoved:(UIButton*) sender withEvent:(UIEvent *) event
 {
point = [[[event allTouches] anyObject] locationInView:self.view];
UIControl *control = sender;
control.center = point;
 [sender addTarget:self action:@selector(touches:withEvent:) forControlEvents:UIControlEventTouchUpInside];
}

-(void)touches:(UIButton *)button withEvent:(UIEvent *)event {

[UIView animateWithDuration:0.1 delay:0 options:UIViewAnimationOptionCurveEaseOut | UIViewAnimationOptionAllowUserInteraction animations:^{
     button.center = point;

 } completion:^(BOOL finished){
     if (finished) {
    // do anything yu want
   }

它很棒,因为我在我的项目中使用它!

答案 2 :(得分:0)

如何在UIControlEventTouchUpInside上调用选择器,然后在选择器中,只需将按钮的框架设置为新的x和y坐标(已保存的坐标)。

答案 3 :(得分:0)

在我所引用的线程中链接到的解决方案中,我创建了一个通用的拖放管理器,它负责将拖动对象返回到原始位置(如果在已知的dropzone之外释放)。目前解决方案中没有动画,但您可以结合上面提到的一些想法。

查看一些generic drag and drop solution in iOS

的内容

答案 4 :(得分:-1)

你知道吗,我昨天刚刚开始研究这个问题,所以在这里你会带一点奖励动画:

- (void)previewImageTouchUpInside:(UIButton*)aButton {
    if (!previewImageDragged) {
        [self selectPreviewImage:aButton];
        return;
}

    previewImageDragged = NO;

    // If user drag photo a little and then release, we'll still treat it as a tap
    //  instead of drag
    if ((originalPositionOfButton.x - aButton.center.x) * 
      (originalPositionOfButton.x - aButton.center.x) + 
      (originalPositionOfButton.y - aButton.center.y) * 
      (originalPositionOfButton.y - aButton.center.y) < 10) {
        aButton.center = originalPositionOfButton;
        [self selectPreviewImage:aButton];
        return;
    }

    [UIView animateWithDuration:0.5
        delay:0
        options:UIViewAnimationOptionCurveEaseOut |
        UIViewAnimationOptionAllowUserInteraction animations:^{
        aButton.center = originalPositionOfButton;
    } completion:nil];
}



- (void)previewImageDraggedInside:(UIButton*)aButton event:(UIEvent*)event {
    if (!previewImageDragged) {
        originalPositionOfButton = aButton.center;
        [self.view bringSubviewToFront:aButton];
        [self.view bringSubviewToFront:[self.view viewWithTag:CHOOSE_PHOTO_BUTTON_TAG]];
    }

    UITouch* touch = [[event allTouches] anyObject];

    previewImageDragged = YES;
    aButton.center = CGPointMake(aButton.center.x+[touch locationInView:self.view].x-
        [touch previousLocationInView:self.view].x, 
        aButton.center.y+[touch locationInView:self.view].y-
        [touch previousLocationInView:self.view].y);
}

它仍然有一些神奇的数字,我没有重命名函数和变量以适合你的例子,但它应该是清楚的。我也在这里做了缩进,因为我没有在我的代码中手动断开长行。