2011-12-31 97 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; 
} 
相关问题