Тип NSPasteboard для NSManagedObject - PullRequest
       3

Тип NSPasteboard для NSManagedObject

2 голосов
/ 13 декабря 2010

Мне нужно перетащить ссылку на NSManagedObject между двумя табличными представлениями моего приложения.Какой предпочитаемый тип NSPasteboard для хранения ссылки на NSManagedObject?

Мое текущее решение - сохранить URIRпредставление объекта NSManagedObjectID в NSPasteboardTypeString.Я подозреваю, что есть более элегантное решение.

Ответы [ 2 ]

3 голосов
/ 13 декабря 2010

Не существует стандартного типа для всех объектов модели, поскольку объекты модели и способ их обработки являются уникальными для вашего приложения.Если бы был один тип картона для всех, то не было бы их рассказывать отдельно.Ваш собственный пользовательский объект должен иметь свой собственный тип перетаскивания.

Просто используйте строку, которая имеет смысл (возможно, #define, чтобы вы могли найти ее с автозаполнением в XCode), например "MyObjectPboardType", которая разрешается в "com.yourcompany.yourapp.yourobjecttype ".

Используйте -declareTypes: owner: NSPasteboard для объявления вашего нового типа, затем используйте -setString: forType: или один из других -set?: forType: методы для установки информациидля типа вашего объекта.В вашем случае использование идентификатора объекта является вполне приемлемым идентификатором.Просто помните, что идентификаторы объектов управляемых объектов меняются, когда они новые и сохраняются.

1 голос
/ 23 февраля 2017

Если вы перетаскиваете внутри таблиц в одном и том же приложении, вы можете также поместить в монтажную область rowIndexes (indexPaths в случае, если вы перетаскиваете из outlineView) объектов в tableView (outlineView).Это также может избавить вас от ненужного доступа к CoreData, если источником данных tableViews является NSArrayController (NSTreeController для outlineView).Затем вы можете легко извлечь перетаскиваемые объекты при принятии отбрасывания, поскольку объект «информация» передается обоим методам.tableView, инициирующий перетаскивание по ключевому пути draggingSource.

Вот простая реализация:

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
}
...