2015-09-05 4 views
2

J'ai un NSTableView que je souhaite être capable de faire glisser et déposer des lignes pour les déplacer, et glisser-déposer tout en maintenant Option (selon Apple's documentation) pour les copier.Comment autoriser le déplacement et la copie en faisant glisser des lignes dans un NSTableView?

J'ai le code suivant dans mon contrôleur de vue, qui est également le dataSource de la vue de table.

- (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. Comment puis-je faire défaut en faisant glisser l'opération se déplacer et être uniquement une copie lorsque la touche Option enfoncée? Actuellement, il est par défaut de copier tout de suite.
  2. Dans tableView:acceptDrop:row:dropOperation: comment puis-je savoir si l'opération était une opération de copie ou une opération de suppression?

Répondre

2

Comme décrit dans this discussion la valeur de draggingSourceOperationMask sera NSDragOperationEvery (sauf modification) en l'absence de touches de modification ont lieu:

Quand il revient à votre table comme une validation de chute sans aucune modification par le utilisateur (pas de touche d'option enfoncée), alors l'une des options d'origine doit être considérée comme étant . Votre validation devrait alors choisir l'opération (parmi les options autorisées par la source) que vous ferez basée sur sur ce qui est logique pour la cible de la chute.

Ce qui signifie que la méthode suivante retourne NSDragOperationCopy lorsque la touche Option enfoncée et NSDragOperationMove autrement:

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

De même, l'opération peut être vérifiée dans le tableView:acceptDrop:row:dropOperation: de la même manière.

0

En validateDrop: retour [info draggingSourceOperationMask] & (NSDragOperationMove | NSDragOperationCopy) ou NSDragOperationNone.

Dans acceptDrop: cochez [info draggingSourceOperationMask] & NSDragOperationMove.

+0

Le 'draggingSourceOperationMask' est -1 quand il suffit de faire glisser l'élément ce qui signifie que' NSDragOperationCopy & NSDragOperationMove' est retourné, quand je veux juste 'NSDragOperationMove'. – DanielGibbs