UITableView:如何禁用将项目拖动到特定行?

时间:2011-08-09 13:42:04

标签: ios uitableview

我有一个带有可拖动行的UITableView,我可以添加/删除项目。数据源是NSMutableArray。

现在,如果我使用“添加新功能”移动该行,则应用程序崩溃,因为dataSource较小,因为尚未添加此行。

所以我修改了这段代码:

- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath {
        if (indexPath.row >= [dataList count]) return NO;
        return YES;
    }

现在我不能再动了。但是,我仍然可以在这样的行之后移动其他行,因此代码崩溃。

我该如何解决这个问题?有没有办法禁用拖动“到”特定行,而不仅仅是从?

感谢

4 个答案:

答案 0 :(得分:38)

这正是UITableViewDelegate方法

-tableView:targetIndexPathForMoveFromRowAtIndexPath:toProposedIndexPath:

是为了。它会适合你的目的吗? Here's文档。

答案 1 :(得分:17)

之前的答案和文档(请参阅其他答案中提到的thisthis)有用但不完整。我需要:

  • 实施例
  • 知道如果建议的行动不合适该怎么办

不用多说,这里有一些

实施例

接受所有动作

- (NSIndexPath *)tableView:(UITableView *)tableView
    targetIndexPathForMoveFromRowAtIndexPath:(NSIndexPath *)sourceIndexPath
                         toProposedIndexPath:(NSIndexPath *)proposedDestinationIndexPath
{
    return proposedDestinationIndexPath;
}

拒绝所有移动,将行返回到其初始位置

- (NSIndexPath *)tableView:(UITableView *)tableView
    targetIndexPathForMoveFromRowAtIndexPath:(NSIndexPath *)sourceIndexPath
                         toProposedIndexPath:(NSIndexPath *)proposedDestinationIndexPath
{
    return sourceIndexPath;
}

拒绝一些移动,将任何被拒绝的行返回到其初始位置

- (NSIndexPath *)tableView:(UITableView *)tableView
    targetIndexPathForMoveFromRowAtIndexPath:(NSIndexPath *)sourceIndexPath
                         toProposedIndexPath:(NSIndexPath *)proposedDestinationIndexPath
{
    if (... some condition ...) {
        return sourceIndexPath;
    }
    return proposedDestinationIndexPath;
}

答案 2 :(得分:8)

如何修改最后一行:

- (NSIndexPath *)tableView:(UITableView *)tableView
targetIndexPathForMoveFromRowAtIndexPath:(NSIndexPath *)sourceIndexPath
       toProposedIndexPath:(NSIndexPath *)proposedDestinationIndexPath
{
    // get number of objects
    NSUInteger numberOfObjects = [[[BNRItemStore sharedStore] allItems] count]; 

    if ( (proposedDestinationIndexPath.row+1==numberOfObjects) || (sourceIndexPath.row+1==numberOfObjects) ) {
        NSLog(@"HERE");
        return sourceIndexPath;
    }
    else{
         NSLog(@"count=%d %d", [[[BNRItemStore sharedStore] allItems] count], proposedDestinationIndexPath.row);
        return proposedDestinationIndexPath;
    }
}

答案 3 :(得分:0)

Following is the example to restrict drag and drop to 0th index of 1st section UICollectionView
It worked for me :)

func collectionView(_ collectionView: UICollectionView, dropSessionDidUpdate session: UIDropSession, withDestinationIndexPath destinationIndexPath: IndexPath?) -> UICollectionViewDropProposal {

        if session.localDragSession != nil
        {
#//restricts dropping to 0th index
            if destinationIndexPath?.row == 0{
               return UICollectionViewDropProposal(operation: .forbidden) 
            }

            if collectionView.hasActiveDrag
            {
                return UICollectionViewDropProposal(operation: .move, intent: .insertAtDestinationIndexPath)
            }
            else
            {
                return UICollectionViewDropProposal(operation: .copy, intent: .insertAtDestinationIndexPath)
            }
        }

    }

    func collectionView(_ collectionView: UICollectionView, itemsForBeginning session: UIDragSession, at indexPath: IndexPath) -> [UIDragItem] {
#//prevents dragging item from 0th index
        if indexPath.row == 0{
            return [UIDragItem]() //prevents dragging item from 0th index
        }

        let item = self.yourArray[indexPath.row]
        let itemProvider = NSItemProvider(object: item)
        let dragItem = UIDragItem(itemProvider: itemProvider)
        dragItem.localObject = item
        return [dragItem]
    }