Как я могу разрешить перемещение и копирование, перетаскивая строки в NSTableView?
У меня есть NSTableView
который я хочу иметь возможность перетаскивать строки, чтобы переместить их, и перетаскивать, удерживая Option (согласно документации Apple), чтобы скопировать их.
У меня есть следующий код в моем контроллере представления, который также 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;
}
- Как сделать так, чтобы операция перетаскивания по умолчанию двигалась и копировалась только тогда, когда нажата клавиша Option? В настоящее время по умолчанию копировать сразу.
- В
tableView:acceptDrop:row:dropOperation:
как я могу узнать, была ли операция копированием или удалением?
2 ответа
Как описано в этом обсуждении значение draggingSourceOperationMask
будет NSDragOperationEvery
(если не изменено), когда клавиши-модификаторы не удерживаются:
Когда он возвращается к вашей таблице как проверка сброса без какой-либо модификации пользователем (без ключа опции), тогда любые из первоначальных опций должны рассматриваться как возможные. Ваша проверка должна затем выбрать операцию (из исходных разрешенных опций), которую вы будете выполнять, основываясь на том, что имеет смысл для цели отбрасывания.
Это означает, что следующий метод вернет NSDragOperationCopy
когда клавиша Option удерживается нажатой, и 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:
аналогичным образом.
В validateDrop: вернуть [info draggingSourceOperationMask] & (NSDragOperationMove | NSDragOperationCopy) или NSDragOperationNone.
В acceptDrop: проверьте [info draggingSourceOperationMask] и NSDragOperationMove.