如何通过拖动NSTableView中的行来允许移动和复制?

时间:2015-09-05 00:32:44

标签: cocoa drag-and-drop nstableview nsdragginginfo

我有NSTableView我希望能够拖放行来移动它们,并在按住Option(按Apple's documentation)的同时进行拖放以复制它们。

我的视图控制器中有以下代码,它也是表视图的dataSource

- (void)awakeFromNib {
    [self.tableView registerForDraggedTypes:@[kRowIndexesPasteboardType]];
}

- (BOOL)tableView:(NSTableView *)tableView writeRowsWithIndexes:(NSIndexSet *)rowIndexes toPasteboard:(NSPasteboard *)pasteboard {
    NSData *data = [NSKeyedArchiver archivedDataWithRootObject:rowIndexes];
    [pasteboard declareTypes:@[kRowIndexesPasteboardType] owner:self];
    [pasteboard setData:data forType:kRowIndexesPasteboardType];
    return YES;
}

- (NSDragOperation)tableView:(NSTableView *)tableView validateDrop:(id <NSDraggingInfo>)info proposedRow:(NSInteger)row proposedDropOperation:(NSTableViewDropOperation)dropOperation {
    // Only allow dropping above/below.
    return dropOperation == NSTableViewDropAbove ? (NSDragOperationMove|NSDragOperationCopy) : NSDragOperationNone;
}

- (BOOL)tableView:(NSTableView *)tableView acceptDrop:(id <NSDraggingInfo>)info row:(NSInteger)row dropOperation:(NSTableViewDropOperation)dropOperation {
    if (dropOperation == NSTableViewDropAbove) {
        NSPasteboard* pasteboard = [info draggingPasteboard];
        NSData* rowData = [pasteboard dataForType:kRowIndexesPasteboardType];
        NSIndexSet* rowIndexes = [NSKeyedUnarchiver unarchiveObjectWithData:rowData];

        BOOL copy = ???;
        if (copy) {
            // Copy items at rowIndexes to row.
        } else {
            // Move items at rowIndexes to row.
        }
        return YES;
    }
    return NO;
}
  1. 如何使默认拖动操作移动,并且仅在按住Option键时进行复制?目前,它默认立即复制。
  2. tableView:acceptDrop:row:dropOperation:中如何判断操作是复制操作还是删除操作?

2 个答案:

答案 0 :(得分:2)

正如this discussion中所述,draggingSourceOperationMask的值在没有修饰键时会NSDragOperationEvery(除非更改):

  

什么时候回来   在没有任何修改的情况下作为drop验证到你的表   用户(没有选项键),然后任何原始选项需要   被认为是可能的。然后你的验证应该选择   您将要执行的操作(源允许的选项)   关于什么是有意义的下降目标。

这意味着当按住Option键时,以下方法将返回NSDragOperationCopy,否则将NSDragOperationMove返回:

- (NSDragOperation)tableView:(NSTableView *)tableView validateDrop:(id <NSDraggingInfo>)info proposedRow:(NSInteger)row proposedDropOperation:(NSTableViewDropOperation)dropOperation {
    // Allow moving or copying the rows.
    NSDragOperation moveOrCopy = (info.draggingSourceOperationMask == NSDragOperationCopy ? NSDragOperationCopy : NSDragOperationMove);
    // Only allow dropping above/below.
    return dropOperation == NSTableViewDropAbove ? moveOrCopy : NSDragOperationNone;
}

同样,可以在tableView:acceptDrop:row:dropOperation:中以类似的方式检查操作。

答案 1 :(得分:0)

在validateDrop中:return [info draggingSourceOperationMask]&amp; (NSDragOperationMove | NSDragOperationCopy)或NSDragOperationNone。

在acceptDrop中:检查[info draggingSourceOperationMask]&amp; NSDragOperationMove。