2011-12-31 94 views
6

我無法使用新的Lion功能重新排列我的應用中的行。我正在使用outlineView:pasteboardWriterForItem:來存儲行索引,以便稍後驗證/接受放置時可以訪問它們。我創建了一個新的NSPasteboardItem返回,並在嘗試行號碼存儲爲這樣:通過在Lion中拖動來重新排列表格行

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

TABLE_VIEW_DATA_TYPE是我用來區分拖拽紙板我的自定義數據的自定義字符串。我不會在拖動這些行之外使用它。

當試圖拖動,我收到控制檯:'TableViewDataType' is not a valid UTI string. Cannot set data for an invalid UTI.

當然,我可以使用一些內置的尿路感染的pasteboards,但沒有人申請(並利用它們使接受拖動拖動其他比行,它不應該)。是否有我缺少的東西,比如定義一個自定義UTI只是爲了拖拽(沒有使它成爲「真正的」UTI,因爲我沒有在內部拖動之外使用它,所以它不應該公開)。

感謝您的幫助!

回答

2

而不是使用香草NSPasteboardItem,您應該創建一個符合NSPasteboardWriting協議的自定義對象。

在您的自定義對象中,您可以實現writableTypesForPasteboard:以返回粘貼板項目支持的自定義UTI列表。然後,實施pasteboardPropertyListForType:以在粘貼板要求時返回適當自定義UTI的對象的plist表示形式。

您可以使用NSPropertyListSerialization+propertyListWithData:options:format:error:方法從任意數據創建plist。

然後,您將在表格視圖數據源中覆蓋tableView:pasteboardWriterForRow:以返回您的自定義對象的實例。

+1

謝謝,欣賞響應。我仍然非常驚訝,因爲跟蹤重新排列的行很複雜。 – livings124 2011-12-31 16:49:17

+0

我實現符合'NSPasteboardWriting'對象返回我的自定義UTI爲'writableTypesForPasteboard:',但我發現:_'TableViewDataType」不是一個有效的UTI字符串。不能使用無效UTI從-writeableTypesForPasteboard返回類型:類TableViewDragNode._ – livings124 2012-01-01 23:32:19

+0

如果是這樣的話,那麼我不認爲你有任何選項,但在你的Info.plist宣佈自定義UTI你拖動操作。我同意,這似乎是一個奇怪的限制。我不相信在運行時定義UTI是可能的,但它必須在Info.plist中進行硬編碼。 – 2012-01-01 23:54:33

5

您可以使用的另一種技術是隻存儲您拖動到一側的實例變量中的對象的索引。除非您接受來自其他應用程序的項目,否則將所有內容放在粘貼板上並不是絕對必要的,反之亦然。

  1. 在awakeFromNib中,註冊NSStringPboardType。
  2. 在... pasteboardWriterForRow中,返回[NSString string]。
  3. 在... draggingSession:willBegin ...中,將您的實例變量設置爲您要跟蹤的索引。
  4. 在validateDrop中,如果實例變量爲nil或視圖不是你的,則返回NSDragOperationNone。
  5. In ... draggingSession:ended ...,將你的實例變量刪掉。

希望有幫助...我使用的技術爲表視圖,但它應該幾乎相同的大綱視圖。

6

我有類似的要求,除了我有一個對象的網格,我想通過拖動選定的對象到一個新的位置重新排列。有這樣做,包括創建一個自定義對象和實施NSPasteboardWritingNSPasteboardReading協議(和NSCoding協議如果你將讀取數據爲NSPasteboardReadingAsKeyedArchive)的幾種方法,但是這似乎是矯枉過正仍然存在內部的物體的拖應用。

我所做的事情包括使用NSPasteboardItem作爲自定義UTI類型(它已實現NSPasteboardWritingNSPasteboardReading協議)的包裝。首先聲明一個自定義的UTI類型:

#define kUTIMyCustomType @「com.mycompany.MyApp.MyCustomType」

這需要在「com.domain.MyApp」格式來定義,否則你會得到出錯的形式:「XXX是不是一個有效的UTI字符串。無法爲無效的UTI設置數據。「Apple在文檔中提到了這一點。

然後,你必須註冊在其中將出現您拖動認爲,這一習俗UTI類型。這可以在運行時完成,並且不需要任何.plist添加。在你看來的init方法添加以下內容:

[self registerForDraggedTypes:[NSArray arrayWithObjects:(NSString *)kUTIMyCustomType, nil]]; 

現在,確保該委託設置爲這一觀點,並委託對象實現了所需的NSDraggingSourceNSDraggingDestination協議方法。這將允許您避免打破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; 
} 
相關問題