【问题标题】:Drag&Drop is not enabled for a NSOutlineView although I've implemented delegate methods尽管我已经实现了委托方法,但没有为 NSOutlineView 启用拖放
【发布时间】:2012-04-02 14:43:36
【问题描述】:

我无法为 NSOutlineView 启用拖放功能。我已经实现了 NSOutlineView Delegate 的相关方法。

但似乎当我单击一个项目时,我什至无法拖动它(我没有看到动画)。

- (BOOL)outlineView:(NSOutlineView *)outlineView acceptDrop:(id < NSDraggingInfo >)info item:(id)item childIndex:(NSInteger)index
{
    return YES;
}

- (NSDragOperation)outlineView:(NSOutlineView *)outlineView validateDrop:(id < NSDraggingInfo >)info proposedItem:(id)item proposedChildIndex:(NSInteger)index
{
    return NSDragOperationMove; //not sure about this one.
}

谢谢

更新:

我正在实施 forOSX >= 10.5

- (BOOL)outlineView:(NSOutlineView *)outlineView writeItems:(NSArray *)items toPasteboard:(NSPasteboard *)pboard
{
    NSString *pasteBoardType = [self pasteboardTypeForTableView:outlineView];
    [pboard declareTypes:[NSArray arrayWithObject:pasteBoardType] owner:self];

    NSData *rowData = [NSKeyedArchiver archivedDataWithRootObject:items];
    [pboard setData:rowData forType:pasteBoardType];
        return YES;
}

【问题讨论】:

    标签: objective-c cocoa


    【解决方案1】:

    您实现的方法仅用于拖动的目的地。您仍然需要实现dragging source methods。无论出于何种原因,Apple 的 NSOutlineViewDataSource Protocol 文档缺少这些方法,但您有两种选择:

    1. 如果您正在构建 10.7+,请使用 Xcode 的 Open Quickly 命令查看 NSOutlineView.h 并找到相关方法。另请查看DragNDropOutlineView 示例应用程序。

    2. 如果您支持以前的操作系统,请使用 NSTableView 的委托方法。见NSTableViewDataSource Protocol Reference。请记住,NSOutlineView 是 NSTableView 的子类,可以使用表格视图方法。

    至少你可能想要实现outlineView:writeItems:toPasteboard:

    /* Dragging Source Support - Optional for single-image dragging. This method is called after
    it has been determined that a drag should begin, but before the drag has been started.  To 
    refuse the drag, return NO.  To start a drag, return YES and place the drag data onto the 
    pasteboard (data, owner, etc...).  The drag image and other drag related information will 
    be set up and provided by the outline view once this call returns with YES.  The items array 
    is the list of items that will be participating in the drag.
    */
    - (BOOL)outlineView:(NSOutlineView *)outlineView writeItems:(NSArray *)items toPasteboard:(NSPasteboard *)pasteboard;
    

    更新:

    如果项目可以拖动但不会放在任何东西上,那么很可能outlineView:validateDrop:proposedItem:proposedChildIndex: 没有被调用。这意味着您还没有注册您使用registerForDraggedTypes: 执行的粘贴板类型。您可以在视图控制器的某个地方执行此操作,可能在 awakeFromNib

    [outlineView registerForDraggedTypes:[NSArray arrayWithObject:@"myPasteBoardType"]];
    

    要移动项目(及其所有子项),请修改 outlineView:acceptDrop:item:childIndex: 中的模型。然后将reloadData 发送到outlineView。

    【讨论】:

    • NSOutlineView拖源方法肯定是in the docs。您无需转到标题即可查看它们。请记住,NSOutlineViewNSTableViewNSView 的子类,并且也继承了这些视图的所有拖放方法。
    • 你说得对,那个就在那里。但像outlineView:draggingSession:willBeginAtPoint:forItems:outlineView:pasteboardWriterForItem: 这样的其他人则不然。
    • 谢谢,我不确定我的方法的实现。我已经更新了我的问题。我需要将 outlineView 的一个项目拖到树中的另一个位置。
    • 我需要拖动项目对象,而不仅仅是一个字符串,因为我必须将其所有子对象移动到新位置。
    • @RobKeniger 不要只相信文档。我挑战你在文档中找到- (id &lt;NSPasteboardWriting&gt;)outlineView:(NSOutlineView *)outlineView pasteboardWriterForItem:(id)item NS_AVAILABLE_MAC(10_7);——即使它就在NSOutlineView.h
    【解决方案2】:

    要使大纲视图成为拖动源,您必须实现:

    - (BOOL)outlineView:(NSOutlineView *)outlineView writeItems:(NSArray *)items toPasteboard:(NSPasteboard *)pasteboard;
    

    这应该解决您所描述的问题,但除此之外您还有很多工作要做。

    【讨论】:

    • 谢谢,我不确定我的方法的实现。我已经更新了我的问题。我需要将 outlineView 的一个项目拖到树中的另一个位置。
    • 我需要拖动项目对象,而不仅仅是一个字符串,因为我必须将其所有子对象移动到新位置。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多