アプリケーションの2つのテーブルビュー間でNSManagedObjectへの参照をドラッグする必要があります。NSManagedObjectへの参照を格納するために推奨されるNSPasteboardタイプは何ですか?
私の現在の解決策は、オブジェクトのNSManagedObjectIDのURIRepresentationをNSPasteboardTypeStringに格納することです。もっとエレガントな解決策があるのではないかと思います。
アプリケーションの2つのテーブルビュー間でNSManagedObjectへの参照をドラッグする必要があります。NSManagedObjectへの参照を格納するために推奨されるNSPasteboardタイプは何ですか?
私の現在の解決策は、オブジェクトのNSManagedObjectIDのURIRepresentationをNSPasteboardTypeStringに格納することです。もっとエレガントな解決策があるのではないかと思います。
モデルオブジェクトとその処理方法はアプリケーションに固有であるため、すべてのモデルオブジェクトに標準のタイプはありません。すべてに1つの厚紙タイプがあった場合、それらを区別することはできません。独自のカスタムオブジェクトには、独自のドラッグタイプが必要です。
「com.yourcompany.yourapp.yourobjecttype」に解決される「MyObjectPboardType」のような意味のある文字列(Xcodeでオートコンプリートで見つけることができるように#defineなど)を使用するだけです。
NSPasteboardの-declareTypes:owner:を使用して新しい型を宣言してから、-setString:forType:または他の-set?:forType:メソッドのいずれかを使用してオブジェクトの型の情報を設定します。あなたの場合、オブジェクトIDの使用は完全に受け入れ可能な識別子です。管理対象オブジェクトのオブジェクトIDは、新しい場合と永続的な場合で変わることを覚えておいてください。
同じアプリケーションのテーブル内でドラッグする場合は、tableView(outlineView)内のオブジェクトのrowIndexes(outlineViewからドラッグする場合はindexPaths)をペーストボードに配置することもできます。これにより、tableViewsのdataSourceがNSArrayController(outlineViewの場合はNSTreeController)である場合、不要なCoreDataアクセスから解放される可能性があります。'info'オブジェクトが両方のメソッド'tableView:validateDrop:proposedRow:proposedDropOperation:'と'tableView:acceptDrop:row:dropOperation:'に渡されるため、ドロップを受け入れるときにドラッグされたオブジェクトを簡単に取得できます。 'draggingSource'キーパスの下のドラッグを開始するtableView。
簡単な実装は次のとおりです。
extern NSString *const kMyLocalDragType = @"com.whatever.localDragType";
@implementation MyArrayControllerDataSource
.
.
.
#pragma mark - NSTableViewDataSource (Drag & Drop)
+ (NSArray *)dragTypes {
// convenience method returning all class's supported dragTypes
return @[kMyLocalDragType];
}
- (BOOL)tableView:(NSTableView *)tableView writeRowsWithIndexes:(NSIndexSet *)rowIndexes toPasteboard:(NSPasteboard *)pboard {
[pboard declareTypes:[[self class] dragTypes] owner:self];
for (NSString *aDragType in [[self class] dragTypes]) {
if (aDragType == kMyLocalDragType) {
NSData *data = [NSKeyedArchiver archivedDataWithRootObject:rowIndexes]; // we are supporting drag&drop of multiple items selected
[pboard setData:data forType:aDragType];
}
.
. // logic for other dragTypes
.
}
return YES;
}
- (NSDragOperation)tableView:(NSTableView *)tableView validateDrop:(id<NSDraggingInfo>)info proposedRow:(NSInteger)row proposedDropOperation:(NSTableViewDropOperation)dropOperation {
NSArray *dragTypes = [info draggingPasteboard] types];
for (id aDragType in dragTypes) {
if (aDragType == kMyLocalDragType) {
return NSDragOperationCopy;
}
}
.
.// Other logic for accepting drops/affect drop operation
.
}
- (BOOL)tableView:(NSTableView *)tableView acceptDrop:(id<NSDraggingInfo>)info row:(NSInteger)row dropOperation:(NSTableViewDropOperation)dropOperation {
if ([info draggingPasteboard] types] containsObject:kMyLocalDragType]) {
// Retrieve the index set from the pasteboard:
NSData *data = [[info draggingPasteboard] dataForType:kMyLocalDragType];
NSIndexSet *rowIndexes = [NSKeyedUnarchiver unarchiveObjectWithData:data];
NSArray *droppedObjects = [self retrieveFromTableView:tableView objectsAtRows:rowIndexes];
// droppedObjects contains dragged and dropped objects, do what you
// need to do with them, then add them to this dataSource:
[self.content insertObjects:droppedObjects];
[tableView reloadData];
[tableView deselectAll:nil];
return YES;
}
.
. // other logic for accepting drops of other dragTypes supported.
.
}
#pragma mark - Helpers
- (NSArray <NSManagedObject *> *)retrieveFromTableView:(NSTableView *)tableView objectsAtRowIndexes:(NSIndexSet *)rowIndexes {
id dataSource = [tableView dataSource];
if ([dataSource respondsToSelector:@selector(content)]) {
if ([dataSource.content respondsToSelector:@selector(objectsAtIndexes:)]) {
return [datasource content] objectsAtIndexes:rowIndexes];
}
}
return @[]; //We return an empty array in case introspection check failed
}