Reputation: 393
I'm a noob on IOS. I have searched a lot, but I didn't find any good tutorial about Drag and Drop on IOS. I just read that is not directly supported. Is that possible to Drag an item from a scroll view to a view, and pass some information with it? Imagine the MAIL app. I want to drag an email to the big view on the right, and pass some information with it. Is there any book, or tutorial, that can teach me how to make it?
TKS!
Upvotes: 1
Views: 3902
Reputation: 438232
It's just a matter of using Gesture Recognizers (see Event Handler Guide).
Actual implementations depends a little upon how you want to do it. Here's a random example where I've got a split view control and I'm dragging something from the tableview on the left into the view on the right, the whole drag and drop triggered by a long press (e.g. a "tap and hold"). Thus, I just create a gesture recognizer in the viewDidLoad of the tableview controller (in my case, the master view controller):
UILongPressGestureRecognizer *longPress = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(longPress:)];
[self.tableView addGestureRecognizer:longPress];
And then I defined a gesture recognizer handler that implements the drag and drop, e.g.,
- (IBAction)longPress:(UIGestureRecognizer *)sender
{
if (sender.state == UIGestureRecognizerStateBegan)
{
// figure out which item in the table was selected
NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint:[sender locationInView:self.tableView]];
if (!indexPath)
{
inDrag = NO;
return;
}
inDrag = YES;
// get the text of the item to be dragged
NSString *text = [NSString stringWithString:[[_objects objectAtIndex:indexPath.row] description]];
// create item to be dragged, in this example, just a simple UILabel
UIView *splitView = self.splitViewController.view;
CGPoint point = [sender locationInView:splitView];
UIFont *font = [UIFont systemFontOfSize:12];
CGSize size = [text sizeWithFont:font];
CGRect frame = CGRectMake(point.x - (size.width / 2.0), point.y - (size.height / 2.0), size.width, size.height);
draggedView = [[UILabel alloc] initWithFrame:frame];
[draggedView setFont:font];
[draggedView setText:text];
[draggedView setBackgroundColor:[UIColor clearColor]];
// now add the item to the view
[splitView addSubview:draggedView];
}
else if (sender.state == UIGestureRecognizerStateChanged && inDrag)
{
// we dragged it, so let's update the coordinates of the dragged view
UIView *splitView = self.splitViewController.view;
CGPoint point = [sender locationInView:splitView];
draggedView.center = point;
}
else if (sender.state == UIGestureRecognizerStateEnded && inDrag)
{
// we dropped, so remove it from the view
[draggedView removeFromSuperview];
// and let's figure out where we dropped it
UIView *detailView = self.detailViewController.view;
CGPoint point = [sender locationInView:detailView];
UIAlertView *alert;
if (CGRectContainsPoint(detailView.bounds, point))
alert = [[UIAlertView alloc] initWithTitle:@"dropped in details view" message:nil delegate:nil cancelButtonTitle:@"Ok" otherButtonTitles:nil];
else
alert = [[UIAlertView alloc] initWithTitle:@"dropped outside details view" message:nil delegate:nil cancelButtonTitle:@"Ok" otherButtonTitles:nil];
[alert show];
}
}
Clearly, if you're dragging a subview from your scrollview, you'd replace the indexPathForRowAtPoint
logic with something like:
UIView *objectToDrag = nil;
CGPoint point = [sender locationInView:myView];
for (UIView *control in myView.subviews)
if (CGRectContainsPoint(control.frame, point))
objectToDrag = control;
if (!objectToDrag)
{
inDrag = NO;
return;
}
That would help you identify what you want to drag, but from there, the logic is very similar (except, rather than dragging the UILabel as in my example, you'd drag your objectToDrag).
Upvotes: 4