2011-12-31 9 views
6

Mam problemy z używaniem nowej funkcji Lwa do zmiany kolejności wierszy w mojej aplikacji. Używam outlineView:pasteboardWriterForItem: do przechowywania indeksów wierszy, aby móc uzyskać do nich dostęp później, gdy potwierdzam/akceptuję zrzut. Tworzę nowy NSPasteboardItem wrócić, a ja próbuje zapisać numer rzędu, jak tak:Zmiana kolejności wierszy tabeli przez przeciąganie w Lion

[pbItem setData: [NSKeyedArchiver archivedDataWithRootObject: [NSNumber numberWithInteger: [fTableView rowForItem: item]]] 
                forType: TABLE_VIEW_DATA_TYPE]; 

TABLE_VIEW_DATA_TYPE to ciąg niestandardowy Używam odróżnić moich danych niestandardowych w kartonowe przeciąganie. Nie używam go poza przeciąganiem tych wierszy.

Podczas próby przeciągania, otrzymuję w konsoli: 'TableViewDataType' is not a valid UTI string. Cannot set data for an invalid UTI.

Oczywiście mogę korzystać z niektórych wbudowany ZUM dla pasteboards, ale żaden z nich nie stosuje się (i korzystania z nich powoduje przeciągnięcie przyjąć ciągnie drugi niż wiersze, których nie powinno). Czy jest coś, czego mi brakuje, na przykład sposób definiowania niestandardowego UTI tylko do przeciągania (bez uczynienia z niego "prawdziwego" UTI, ponieważ nie używam go poza wewnętrznym przeciąganiem, więc nie powinien być publiczny).

Dzięki za pomoc!

Odpowiedz

2

Zamiast używać wanilii NSPasteboardItem, należy utworzyć niestandardowy obiekt zgodny z protokołem NSPasteboardWriting.

W niestandardowym obiekcie można zaimplementować writableTypesForPasteboard:, aby zwrócić listę niestandardowych identyfikatorów UTI, które obsługuje dany element. Następnie zaimplementujesz pasteboardPropertyListForType:, aby zwrócić plist reprezentację obiektu dla odpowiedniego niestandardowego identyfikatora UTI, gdy pyta o to teczka.

Możesz utworzyć plik plist z dowolnych danych, korzystając z metody +propertyListWithData:options:format:error: z NSPropertyListSerialization.

Następnie można zastąpić tableView:pasteboardWriterForRow: w źródle danych widoku tabeli, aby zwrócić wystąpienie niestandardowego obiektu.

+1

Dzięki, doceniam odpowiedź. Nadal jestem bardzo zaskoczony, że tak skomplikowane jest śledzenie zmieniających się rzędów. – livings124

+0

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

+0

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

5

Inną techniką, której można użyć, jest przechowywanie indeksów obiektów, które przeciągasz, w zmiennej instancji na boku. Umieszczenie wszystkiego na stole montażowym nie jest bezwzględnie konieczne, chyba że akceptujesz produkty z innej aplikacji lub odwrotnie.

  1. W awakeFromNib, zarejestruj się w NSStringPboardType.
  2. W ... pasteboardWriterForRow, return [ciąg NSString].
  3. W ... przeciągającSession: willBegin ..., ustaw zmienną instancji na indeksy, które chcesz śledzić.
  4. W validateDrop, zwróć wartość NSDragOperationNone, jeśli zmienna instancji ma wartość zero lub widok nie jest twój.
  5. In ... przeciągnięcieSession: zakończone ..., usuń zmienną instancji.

Nadzieję, że pomaga ... Używam techniki widoku tabeli, ale powinien być praktycznie identyczny dla widoku konspektu.

6

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; 
} 
Powiązane problemy