Basic Drag and Drop in iOS Basic Drag and Drop in iOS ios ios

Basic Drag and Drop in iOS


Assume you have a UIView scene with a background image and many vehicles, you may define each new vehicle as a UIButton (UIImageView will probably work too):

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

Then you may move the vehicle wherever you want, by responding to the UIControlEventTouchDragInside event, e.g.:

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

It's a lot easier for individual vehicle to handle its own drags, comparing to manage the scene as a whole.


In addition to ohho's answer I've tried similar implementation, but without problem of "fast" drag and centering to drag.

The button initialization is...

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

and method implementation:

- (IBAction) imageMoved:(id) sender withEvent:(UIEvent *) event{    UIControl *control = sender;    UITouch *t = [[event allTouches] anyObject];    CGPoint pPrev = [t previousLocationInView:control];    CGPoint p = [t locationInView:control];    CGPoint center = control.center;    center.x += p.x - pPrev.x;    center.y += p.y - pPrev.y;    control.center = center;}

I don't say, that this is the perfect solution for the answer. Nevertheless I found this the easiest solution for dragging.


I had a case where I would like to drag/drop uiviews between multiple other uiviews. In that case I found the best solution to trace the pan events in a super view containing all the drop zones and all the drag gable objects. The primary reason for NOT adding the event listeners to the actual dragged views was that I lost the ongoing pan events as soon as I changed superview for the dragged view.

Instead I implemented a rather generic drag drop solution that could be used on single or multiple drop zones.

I have created a simple example that can be seen here: Drag an drop uiviews between multiple other uiviews

If you decide to go the other way, try using uicontrol instead of uibutton. They declare the addTarget methods and are much easier to extend - hence give custom state and behavior.