【问题标题】:How to reorder rows in NSTableView?如何重新排序 NSTableView 中的行?
【发布时间】:2016-01-30 18:53:41
【问题描述】:

我似乎无法找到一种快速简便的方法来简单地重新排序 NSTableView(OSX 中的行,而不是 iOS)中的行。在 iOS 上,我会使用这两种委托方法:

// Override to support conditional rearranging of the table view.
- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath
{
    return YES;
}

// Override to support rearranging the table view.
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath
{
    MyObject *obj = [model objectAtIndex:fromIndexPath.row];
    [model removeObject:obj]; 
    [model insertObject:obj atIndex:toIndexPath.row];
}

是否有任何快速简便的方法可以为 Cocoa 中的 NSTableView 做类似的事情?到目前为止,我只发现了一些使用粘贴板的大量代码示例,对于我来说,这对于简单的重新排序功能来说似乎有点过头了。

【问题讨论】:

  • 重新排序数据源并告诉tableview重绘。
  • 这部分对我来说很清楚 - 我的问题是实际拖动重新排序。在 iOS 上,这已经实现并自动发生。我想为 NSTableView 重现类似的行为,即单击并按住,然后将行拖动到新位置。
  • 它在 OSX 下更通用,因为它用于拖放(即您可以允许将文件从 Finder 拖到您的表格视图中)。查看NSTableView 类参考的Dragging 部分。
  • 谢谢,通过@ElTomato 的链接找到了一个简单的解决方案。我发布了我易于复制的代码作为这个问题的解决方案。

标签: objective-c macos cocoa nstableview


【解决方案1】:

谢谢大家,现在这对我来说非常有效:

//add line somewhere in your code
#define MyPrivateTableViewDataType @"MyPrivateTableViewDataType"

//add line in your viewDidLoad: method
[self.tableView registerForDraggedTypes:[NSArray arrayWithObject:MyPrivateTableViewDataType]

可以将这些数据源方法复制到代码中而无需任何更改:

// drag operation stuff
- (BOOL)tableView:(NSTableView *)tv writeRowsWithIndexes:(NSIndexSet *)rowIndexes toPasteboard:(NSPasteboard*)pboard {
    // Copy the row numbers to the pasteboard.
    NSData *zNSIndexSetData = [NSKeyedArchiver archivedDataWithRootObject:rowIndexes];

    [pboard declareTypes:[NSArray arrayWithObject:MyPrivateTableViewDataType] owner:self];

    [pboard setData:zNSIndexSetData forType:MyPrivateTableViewDataType];

    return YES;
}

- (NSDragOperation)tableView:(NSTableView*)tv validateDrop:(id )info proposedRow:(NSInteger)row proposedDropOperation:(NSTableViewDropOperation)op {
    // Add code here to validate the drop
    return NSDragOperationEvery;
}

这部分需要实现自定义模型,就像我上面的问题一样:

- (BOOL)tableView:(NSTableView *)aTableView acceptDrop:(id )info row:(NSInteger)row dropOperation:(NSTableViewDropOperation)operation {

    NSPasteboard* pboard = [info draggingPasteboard];
    NSData* rowData = [pboard dataForType:MyPrivateTableViewDataType];
    NSIndexSet* rowIndexes = [NSKeyedUnarchiver unarchiveObjectWithData:rowData];
    NSInteger dragRow = [rowIndexes firstIndex];





    if (dragRow < row) {
        [model insertObject:[model objectAtIndex:dragRow] atIndex:row];
        [model removeObjectAtIndex:dragRow];

        [aTableView noteNumberOfRowsChanged];
        [aTableView moveRowAtIndex:dragRow toIndex:row-1];

    }else {
        ModelObj *obj = [model objectAtIndex:dragRow];
        [model removeObjectAtIndex:dragRow];
        [model insertObject:obj atIndex:row];

        [aTableView noteNumberOfRowsChanged];
        [aTableView moveRowAtIndex:dragRow toIndex:row];
    }

    return YES;
}

【讨论】:

  • @optz 这对我来说非常有效——为我节省了大量时间!感谢您发布它!一个注意事项:我尝试使用 NSTableViewDraggingDestinationFeedbackStyleGap,它在从底部向上拖动时无法正常工作 - 它不会为第二行到底行创建间隙,从而导致在拖动时叠印移动的行文本。从顶部向下拖动确实有效。我放弃了 NSTableViewDraggingDestinationFeedbackStyleRegular。
猜你喜欢
  • 1970-01-01
  • 2011-01-08
  • 2013-07-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多