Miałem podobne wymagania, z wyjątkiem tego, że miałem siatkę obiektów, które chciałem zmienić, przeciągając wybrane obiekty do nowej lokalizacji.Jest na to kilka sposobów, w tym tworzenie niestandardowego obiektu i implementowanie protokołów NSPasteboardWriting
i (i protokołów NSCoding
, jeśli będziesz czytać dane jako NSPasteboardReadingAsKeyedArchive
), ale wydaje się to być przesadą dla przeciągania obiektów, które pozostają wewnętrzne dla podanie.
To, co zrobiłem, polega na użyciu NSPasteboardItem
jako opakowania z niestandardowym typem UTI (już implementuje on protokoły NSPasteboardWriting
i NSPasteboardReading
). Najpierw zadeklarować niestandardowy typ UTI:
#define kUTIMyCustomType @“com.mycompany.MyApp.MyCustomType”
To musi być zdefiniowana w formacie „” com.domain.MyApp inaczej dostaniesz błędy w postaci: „XXX nie jest prawidłowy ciąg UTI. Nie można ustawić danych dla niepoprawnego UTI. "Apple wspomina o tym w swojej dokumentacji.
Następnie należy zarejestrować ten niestandardowy typ UTI w widoku, w którym nastąpi przeciąganie. Można to zrobić w czasie wykonywania i nie wymaga żadnych dodatków .plist. W metodzie init, Pana zdaniem jest dodać następujące:
[self registerForDraggedTypes:[NSArray arrayWithObjects:(NSString *)kUTIMyCustomType, nil]];
Teraz upewnij się, że pełnomocnik jest ustawiony dla tego widoku, a obiekt delegat realizuje wymagane NSDraggingSource
i NSDraggingDestination
metod protokołu. Pozwoli to uniknąć łamania wzorca projektowego MVC, umożliwiając wyznaczonemu obiektowi kontrolera obsługę umieszczenia danych na stole montażowym, co prawdopodobnie będzie wymagać sprawdzenia danych modelu (tj. Indeksów).
szczególności w celu wprowadzenia do przeciągania kartonowe indeksy obiektów mają być przeniesione podczas przeciągania rozpoczyna się NSPasteboardItem
obwolut swoich danych index:
- (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];
}
A kiedy operacja przeciągania zakończeniu odczytu przeciągany indeks NSPasteboardItem
data:
- (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;
}
Dzięki, doceniam odpowiedź. Nadal jestem bardzo zaskoczony, że tak skomplikowane jest śledzenie zmieniających się rzędów. – livings124
Zaimplementowałem obiekt zgodny z 'NspasteboardWriting', który zwraca moje niestandardowe UTI dla' writableTypesForPasteboard: ', ale otrzymuję: _ 'TableViewDataType' nie jest prawidłowym ciągiem UTI. Nie można użyć niepoprawnego UTI jako typu zwróconego z -writeableTypesForPasteboard: w klasie TableViewDragNode._ – livings124
Jeśli tak jest, to nie sądzę, że masz jakąś opcję, ale zadeklarujesz niestandardowe UTI dla operacji przeciągania w twojej Info.plist. Zgadzam się, to dziwne ograniczenie. Nie sądzę, że można zdefiniować UTI w czasie wykonywania, musi być zakodowana na stałe w Info.plist. –