У меня были аналогичные требования, за исключением того, что у меня была сетка объектов, которые я хотел изменить, перетаскивая выбранные объекты в новое место. Есть несколько способов сделать это, включая создание пользовательского объекта и реализацию протоколов NSPasteboardWriting
и NSPasteboardReading
(и протоколов NSCoding
, если вы будете считывать данные как NSPasteboardReadingAsKeyedArchive
), но это кажется излишним для перетаскивания объектов, которые остаются внутренними для заявление.
То, что я сделал, включает использование NSPasteboardItem
в качестве оболочки с пользовательским типом UTI (он уже реализует протоколы NSPasteboardWriting
и NSPasteboardReading
). Сначала объявите пользовательский тип UTI:
#define kUTIMyCustomType @“com.mycompany.MyApp.MyCustomType”
Это необходимо определить в формате «com.domain.MyApp», иначе вы получите ошибки вида: «XXX не является допустимой строкой UTI. Невозможно установить данные для недействительного UTI». Apple упоминает об этом в своей документации.
Затем вы должны зарегистрировать этот пользовательский тип UTI в представлении, в котором будет происходить перетаскивание. Это можно сделать во время выполнения и не требует каких-либо дополнений .plist. В методе инициализации вашего представления добавьте следующее:
[self registerForDraggedTypes:[NSArray arrayWithObjects:(NSString *)kUTIMyCustomType, nil]];
Теперь убедитесь, что делегат установлен для этого представления, а объект делегата реализует необходимые методы протокола NSDraggingSource
и NSDraggingDestination
. Это позволит вам не нарушать шаблон проектирования MVC, позволяя назначенному объекту контроллера обрабатывать размещение данных на монтажном столе, что, вероятно, потребует запроса данных модели (т. е. индексов).
В частности, для размещения на монтажном столе перетаскивания индексов объектов, которые будут перемещены, когда перетаскивание начинается как NSPasteboardItem
обертки ваших данных индекса:
- (void) draggingSession:(NSDraggingSession *)session willBeginAtPoint:(NSPoint)screenPoint
{
NSPasteboard * pboard = [NSPasteboard pasteboardWithName:NSDragPboard];
[pboard clearContents];
NSMutableArray * selectedIndexes = [NSMutableArray array];
// Add NSString indexes for dragged items to pasteboard in NSPasteboardItem wrappers.
for (MyModel * myModel in [self selectedObjects])
{
NSPasteboardItem * pasteboardItem = [[[NSPasteboardItem alloc] init] autorelease];
[pasteboardItem setString:[NSString stringWithFormat:@"%@", [myModel index]]
forType:kUTIMyCustomType];
[selectedIndexes addObject:pasteboardItem];
}
[pboard writeObjects:selectedIndexes];
}
И когда операция перетаскивания завершится, чтобы прочитать данные перетаскиваемого индекса NSPasteboardItem
:
- (BOOL) performDragOperation:(id <NSDraggingInfo>)sender
{
NSPasteboard * pasteboard = [sender draggingPasteboard];
// Check for custom NSPasteboardItem's which wrap our custom object indexes.
NSArray * classArray = [NSArray arrayWithObject:[NSPasteboardItem class]];
NSArray * items = [pasteboard readObjectsForClasses:classArray options:[NSDictionary dictionary]];
if (items == nil)
return NO;
// Convert array of NSPasteboardItem's with NSString index reps. to array of NSNumber indexes.
NSMutableArray * indexes = [NSMutableArray array];
for (NSPasteboardItem * item in items)
[indexes addObject:[NSNumber numberWithInteger:[[item stringForType:kUTIMyCustomType] integerValue]]];
//
// Handle dragged indexes…
//
return YES;
}
person
Dalmazio
schedule
24.12.2013