uitableview - 如何为 iPad 创建类似于 safari 工具栏自定义的拖放操作

标签 uitableview ios5 drag-and-drop

我有一个 UIViewController,上面有一个 UITable 和一个 UIView。我希望能够拾取 UIView 中显示的项目并将它们放到 UITableView 中的单元格上。我必须恢复使用触摸事件而不是新的 UIGestureRecognisers 来拍摄点击的 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。任何想法都非常受欢迎。

最佳答案

我想我已经使用最新的手势识别器提出了更好的解决方案来解决这个问题。我在基本 TableView Controller 中使用以下 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];

最后您需要做的就是像这样实现委托(delegate)方法,

- (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;
    }
}

您可以找到此内容的来源 here 。我花了很长时间才做到这一点,所以我真的希望这可以节省其他人的时间。

关于uitableview - 如何为 iPad 创建类似于 safari 工具栏自定义的拖放操作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7961712/

相关文章:

java - 放弃其他应用程序对 Java 应用程序的支持

ios - UIImage 从 json 请求返回 nil 到 tableView 单元格图像的 mysql 数据库?

iOS5 无法读取 Riven.bundle 的符号(找不到文件)

ios - 如何从数据源来自另一个 swift 文件的 tableView 激活 segue?

iphone - iOS:[imagePickerController.cameraOverlayView addSubview:] 不工作

ios - 在 iOS 5 的 map 上放置 CLPlacemark

javascript - 如何在不重新加载整个页面的情况下在 HTML 框中编写 <div> 代码

c# - 在文本框中拖动文件或文件夹? C#

swift - 从 TableView 单元格内部修改 TableView 单元格数据

ios - 如何在 IOS Swift 4 的 Uitableviewcell 中递增和递减变量