我有類似的要求,除了我有一個對象的網格,我想通過拖動選定的對象到一個新的位置重新排列。有這樣做,包括創建一個自定義對象和實施NSPasteboardWriting
和NSPasteboardReading
協議(和NSCoding
協議如果你將讀取數據爲NSPasteboardReadingAsKeyedArchive
)的幾種方法,但是這似乎是矯枉過正仍然存在內部的物體的拖應用。
我所做的事情包括使用NSPasteboardItem
作爲自定義UTI類型(它已實現NSPasteboardWriting
和NSPasteboardReading
協議)的包裝。首先聲明一個自定義的UTI類型:
#define kUTIMyCustomType @「com.mycompany.MyApp.MyCustomType」
這需要在「com.domain.MyApp」格式來定義,否則你會得到出錯的形式:「XXX是不是一個有效的UTI字符串。無法爲無效的UTI設置數據。「Apple在文檔中提到了這一點。
然後,你必須註冊在其中將出現您拖動認爲,這一習俗UTI類型。這可以在運行時完成,並且不需要任何.plist添加。在你看來的init方法添加以下內容:
[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;
}
謝謝,欣賞響應。我仍然非常驚訝,因爲跟蹤重新排列的行很複雜。 – livings124 2011-12-31 16:49:17
我實現符合'NSPasteboardWriting'對象返回我的自定義UTI爲'writableTypesForPasteboard:',但我發現:_'TableViewDataType」不是一個有效的UTI字符串。不能使用無效UTI從-writeableTypesForPasteboard返回類型:類TableViewDragNode._ – livings124 2012-01-01 23:32:19
如果是這樣的話,那麼我不認爲你有任何選項,但在你的Info.plist宣佈自定義UTI你拖動操作。我同意,這似乎是一個奇怪的限制。我不相信在運行時定義UTI是可能的,但它必須在Info.plist中進行硬編碼。 – 2012-01-01 23:54:33