【问题标题】:How can I allow moving and copying by dragging rows in an NSTableView?如何通过在 NSTableView 中拖动行来允许移动和复制?
【发布时间】:2015-09-05 00:32:43
【问题描述】:

我有一个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: 中如何判断该操作是复制操作还是删除操作?

【问题讨论】:

    标签: cocoa drag-and-drop nstableview nsdragginginfo


    【解决方案1】:

    this discussion 中所述,当没有修改键时,draggingSourceOperationMask 的值将是 NSDragOperationEvery(除非更改):

    当它回来时 到您的表作为删除验证,无需任何修改 用户(没有选项键按下),那么任何原始选项都需要 认为是可能的。然后您的验证应该选择 您将基于的操作(在源允许的选项之外) 关于什么对放置目标有意义。

    这意味着当按住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: 中检查该操作。

    【讨论】:

      【解决方案2】:

      在 validateDrop 中:返回 [info draggingSourceOperationMask] & (NSDragOperationMove | NSDragOperationCopy) 或 NSDragOperationNone。

      在 acceptDrop 中:检查 [info draggingSourceOperationMask] 和 NSDragOperationMove。

      【讨论】:

      • 当我只想要NSDragOperationMove 时,仅拖动项目时draggingSourceOperationMask 为-1,这意味着返回NSDragOperationCopy &amp; NSDragOperationMove
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-09-06
      • 2016-01-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-02-23
      相关资源
      最近更新 更多