objective-c - 在拖放过程中在 NSTableView 中打开一个缺口

标签 objective-c macos cocoa drag-and-drop nstableview

我有一个简单的、单列的、基于 View 的 NSTableView,其中包含可以拖动以重新排序的项目。在拖放过程中,我想让它在鼠标下方的位置打开要放置的项目的间隙。当您拖动以重新排序轨道时,GarageBand 会执行类似的操作(此处的视频:http://www.screencast.com/t/OmUVHcCNSl)。据我所知,NSTableView 中没有对此的内置支持。

有没有其他人尝试将此行为添加到 NSTableView 并找到了一个好的解决方案?我已经想到并尝试了几种方法但没有太大成功。我的第一个想法是通过在我的数据源的 -tableView:validateDrop:... 方法中发送 -noteHeightOfRowsWithIndexesChanged: 来在拖动过程中将鼠标下方行的高度加倍,然后在 -tableView:heightOfRow: 中返回正常高度的两倍。不幸的是,据我所知,NSTableView 在拖放期间不会更新其布局,因此尽管调用了 noteHeightOfRowsWithIndexesChanged:,行高实际上并未更新。

请注意,我使用的是基于 View 的 NSTableView,但我的行并没有复杂到我无法移动到基于单元格的 TableView (如果这样做有助于实现此目的)。我知道在拖动完成后为放置的项目制作间隙动画的简单内置功能。我正在寻找一种在拖动过程中打开间隙的方法。此外,这是针对要在 Mac App Store 中销售的应用程序,因此它不得使用私有(private) API。

编辑:我刚刚向 Apple 提交了增强请求,请求内置支持此行为:http://openradar.appspot.com/12662624 . 如果你也想看到它,请上当。 更新:我要求的增强功能已在 OS X 10.9 Mavericks 中实现,现在可以使用 NSTableView API 实现此行为。参见 NSTableViewDraggingDestinationFeedbackStyleGap .

最佳答案

我觉得这样做很奇怪,但是这里的队列中有一个非常详尽的答案,似乎已被其作者删除。在其中,他们提供了the correct links to a working solution ,我觉得需要将其作为答案呈现给其他人接受和使用,如果他们愿意的话也包括在内。

来自 NSTableView 的文档, 以下注意事项隐藏在行动画效果中:

Row Animation Effects

Optional constant that specifies that the tableview will use a fade for row or column removal. The effect can be combined with any NSTableViewAnimationOptions constant.

enum {
    NSTableViewAnimationEffectFade = 0x1,
    NSTableViewAnimationEffectGap = 0x2,
};

Constants:

...

NSTableViewAnimationEffectGap

Creates a gap for newly inserted rows. This is useful for drag and drop animations that animate to a newly opened gap and should be used in the delegate method tableView:acceptDrop:row:dropOperation:.

通过 the example code from Apple ,我发现这个:

- (void)_performInsertWithDragInfo:(id <NSDraggingInfo>)info parentNode:(NSTreeNode *)parentNode childIndex:(NSInteger)childIndex {
    // NSOutlineView's root is nil
    id outlineParentItem = parentNode == _rootTreeNode ? nil : parentNode;
    NSMutableArray *childNodeArray = [parentNode mutableChildNodes];
    NSInteger outlineColumnIndex = [[_outlineView tableColumns] indexOfObject:[_outlineView outlineTableColumn]];

    // Enumerate all items dropped on us and create new model objects for them    
    NSArray *classes = [NSArray arrayWithObject:[SimpleNodeData class]];
    __block NSInteger insertionIndex = childIndex;
    [info enumerateDraggingItemsWithOptions:0 forView:_outlineView classes:classes searchOptions:nil usingBlock:^(NSDraggingItem *draggingItem, NSInteger index, BOOL *stop) {
        SimpleNodeData *newNodeData = (SimpleNodeData *)draggingItem.item;
        // Wrap the model object in a tree node
        NSTreeNode *treeNode = [NSTreeNode treeNodeWithRepresentedObject:newNodeData];
        // Add it to the model
        [childNodeArray insertObject:treeNode atIndex:insertionIndex];
        [_outlineView insertItemsAtIndexes:[NSIndexSet indexSetWithIndex:insertionIndex] inParent:outlineParentItem withAnimation:NSTableViewAnimationEffectGap];
        // Update the final frame of the dragging item
        NSInteger row = [_outlineView rowForItem:treeNode];
        draggingItem.draggingFrame = [_outlineView frameOfCellAtColumn:outlineColumnIndex row:row];

        // Insert all children one after another
        insertionIndex++;
    }];

}

我不确定它是否真的这么简单,但如果它不能满足您的需求,它至少值得检查和彻底反驳。

编辑:查看此答案的评论以了解正确解决方案所遵循的步骤。 OP 已发布 a more complete answer ,任何寻找相同问题解决方案的人都应该引用。

关于objective-c - 在拖放过程中在 NSTableView 中打开一个缺口,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10142675/

相关文章:

iOS 加密通知声音

java - 使用小程序在 Mac OSX 上从剪贴板抓取图像

objective-c - NSTextField 光标仅在第二次鼠标输入时更改

cocoa - Core Data基于文档的应用程序: saves,但无法加载

swift - 以编程方式退出终端 Mac 应用程序?

objective-c - 如何自动弹出到上一个viewController?

objective-c - 从包含\0 个字符的 char 数组创建 NSString?

ios - 在 iOS 8 中,如何在 la Mail.app 中实现长扫删除手势

ios - 无法解锁钥匙串(keychain)

java - JDK 9 + Mac OS + jlink?