Uitableview 如何为iPad创建类似safari工具栏定制的拖放功能

Uitableview 如何为iPad创建类似safari工具栏定制的拖放功能,uitableview,ios5,drag-and-drop,Uitableview,Ios5,Drag And Drop,我有一个UIViewController,上面有一个UITable和一个UIView。我希望能够拾取显示在UIView中的项目并将其放到UITableView中的单元格中。我必须恢复使用触摸事件而不是新的UIGestureRecognitors来拍摄点击的UIView的快照,以便将此快照拖到UITableView而不是UIView。使用以下命令,这非常有效: -(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{

我有一个UIViewController,上面有一个UITable和一个UIView。我希望能够拾取显示在UIView中的项目并将其放到UITableView中的单元格中。我必须恢复使用触摸事件而不是新的UIGestureRecognitors来拍摄点击的UIView的快照,以便将此快照拖到UITableView而不是UIView。使用以下命令,这非常有效:

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
    UITouch *t =[touches anyObject];

    UIGraphicsBeginImageContext(t.view.bounds.size);
    [t.view.layer renderInContext:UIGraphicsGetCurrentContext()];
    UIImage * img = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    self.draggedView = [[UIImageView alloc] initWithImage:img];

    CGPoint centre = [[touches anyObject] locationInView:self.view];
    [self.draggedView setCenter:centre];
    [self.draggedView setAlpha:0.5];
    [self.view addSubview:self.draggedView];   
}

但是,在touchesEnded事件中,当我尝试评估触摸在哪个UIView上结束时,我总是得到一个UIView,而不是我在UITableView上放置时得到的UIView。任何想法都是非常受欢迎的。

因此,我提出的解决方案允许我将视图拖放到表视图单元格上,设置单元格图像属性以匹配正在拖动的UIView,如下所示

首先,我必须实现touchMoved来移动alpha混合视图,因为它被拖到要放置它的单元格上

-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event{
    CGPoint centre = [[touches anyObject] locationInView:self.view];
    [self.draggedView setCenter:centre];

}
然后在touchSended上,我对tableview进行了命中测试,返回UITableViewCellContentView(UIView*hit)。通过询问hit view的superview,您可以获得单元格hit,从而可以设置其图像

-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{

    CGPoint centre = [[touches anyObject] locationInView:self.view];
    UIView *hit = [self.tableView hitTest:centre withEvent:event];

    UIGraphicsBeginImageContext(self.draggedView.bounds.size);
    [self.draggedView.layer renderInContext:UIGraphicsGetCurrentContext()];
    UIImage * img = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    if(hit!=nil){
        UITableViewCell *tvc = (UITableViewCell *)hit.superview;
        [tvc.imageView setImage:img];
    }

    [self.draggedView removeFromSuperview];
    self.draggedView = nil;
}

希望这对某人有所帮助。

我想我已经用最新的手势识别器找到了更好的解决方案。我在基本TableView控制器中使用以下LongPress手势识别器

- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer{
    if([gestureRecognizer isKindOfClass:[UILongPressGestureRecognizer class]]){
        [gestureRecognizer addTarget:self action:@selector(longGestureAction:)];
    }
    return YES;
}

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer{
    return YES;
}

-(void)longGestureAction:(UILongPressGestureRecognizer *)gesture{
    UITableViewCell *cell= (UITableViewCell *)[gesture view];

    switch ([gesture state]) {
        case UIGestureRecognizerStateBegan:{          
            NSIndexPath *ip = [self.tableView indexPathForCell:cell];
            [self.tableView setScrollEnabled:NO];
            if(ip!=nil){
                [self.draggableDelegate dragAndDropTableViewController:self  draggingGestureWillBegin:gesture forCell:cell];
                UIView *draggedView = [self.draggableDelegate dragAndDropTableViewControllerView:self ];
                //switch the view the gesture is associated with this will allow the dragged view to continue on where the cell leaves off from
                [draggedView addGestureRecognizer:[[cell gestureRecognizers]objectAtIndex:0]]; 
                [self.draggableDelegate dragAndDropTableViewController:self draggingGestureDidBegin:gesture forCell:cell];
            }
        }
            break;
        case UIGestureRecognizerStateChanged:{
            [self.draggableDelegate dragAndDropTableViewController:self draggingGestureDidMove:gesture];
        }
            break;
        case UIGestureRecognizerStateEnded:{
            UIView *draggedView = [self.draggableDelegate dragAndDropTableViewControllerView:self];
            if(draggedView==nil)
                return;

            //this does not seem like the best way to do this yet you really don't want to fire one after the other I don't think
            [self.draggableDelegate dragAndDropTableViewController:self draggingGestureDidEnd:gesture];
            [self.dropableDelegate dragAndDropTableViewController:self droppedGesture:gesture];           

            [self.tableView setScrollEnabled:YES];
            [self.tableView reloadData];
        }
            break;

//        case UIGestureRecognizerStateCancelled:
//        case UIGestureRecognizerStateFailed:
//        case UIGestureRecognizerStatePossible:
//            [self.dragAndDropDelegate dragAndDropTableViewController:self draggingGesture:gesture endedForItem:nil];
            break;
        default:
            break;
    }
}
在扩展该基类的TableView中,我向cellForIndexPath TableViewDataSource中的每个单元格添加了以下内容:

UILongPressGestureRecognizer *longPress = [[UILongPressGestureRecognizer alloc] initWithTarget:cell action:nil];
longPress.delegate = self;
[cell addGestureRecognizer:longPress];
最后,您需要做的就是实现委托方法

- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer{
    if([gestureRecognizer isKindOfClass:[UILongPressGestureRecognizer class]]){
        [gestureRecognizer addTarget:self action:@selector(longGestureAction:)];
    }
    return YES;
}

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer{
    return YES;
}

-(void)longGestureAction:(UILongPressGestureRecognizer *)gesture{
    UITableViewCell *cell= (UITableViewCell *)[gesture view];

    switch ([gesture state]) {
        case UIGestureRecognizerStateBegan:{          
            NSIndexPath *ip = [self.tableView indexPathForCell:cell];
            [self.tableView setScrollEnabled:NO];
            if(ip!=nil){
                [self.draggableDelegate dragAndDropTableViewController:self  draggingGestureWillBegin:gesture forCell:cell];
                UIView *draggedView = [self.draggableDelegate dragAndDropTableViewControllerView:self ];
                //switch the view the gesture is associated with this will allow the dragged view to continue on where the cell leaves off from
                [draggedView addGestureRecognizer:[[cell gestureRecognizers]objectAtIndex:0]]; 
                [self.draggableDelegate dragAndDropTableViewController:self draggingGestureDidBegin:gesture forCell:cell];
            }
        }
            break;
        case UIGestureRecognizerStateChanged:{
            [self.draggableDelegate dragAndDropTableViewController:self draggingGestureDidMove:gesture];
        }
            break;
        case UIGestureRecognizerStateEnded:{
            UIView *draggedView = [self.draggableDelegate dragAndDropTableViewControllerView:self];
            if(draggedView==nil)
                return;

            //this does not seem like the best way to do this yet you really don't want to fire one after the other I don't think
            [self.draggableDelegate dragAndDropTableViewController:self draggingGestureDidEnd:gesture];
            [self.dropableDelegate dragAndDropTableViewController:self droppedGesture:gesture];           

            [self.tableView setScrollEnabled:YES];
            [self.tableView reloadData];
        }
            break;

//        case UIGestureRecognizerStateCancelled:
//        case UIGestureRecognizerStateFailed:
//        case UIGestureRecognizerStatePossible:
//            [self.dragAndDropDelegate dragAndDropTableViewController:self draggingGesture:gesture endedForItem:nil];
            break;
        default:
            break;
    }
}
你可以找到这个的来源。我花了很长时间才把它做好,所以我真的希望这能节省别人的时间