Objective c 如何在NSTableView中对行重新排序?

Objective c 如何在NSTableView中对行重新排序?,objective-c,macos,cocoa,nstableview,Objective C,Macos,Cocoa,Nstableview,我似乎找不到一种简单快捷的方法在NSTableView(OSX one,而不是iOS)中对行重新排序。在iOS上,我将使用以下两种委托方法: // Override to support conditional rearranging of the table view. - (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath { return YES; } //

我似乎找不到一种简单快捷的方法在NSTableView(OSX one,而不是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,是否有任何快速简便的方法可以执行类似的操作?到目前为止,我只发现了一些使用粘贴板的大量代码示例,对我来说,对于简单的重新排序功能来说,这似乎是一种过度使用

谢谢各位,这正是我现在的工作方式:

//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;
}
-(BOOL)tableView:(nsttableview*)aTableView acceptDrop:(id)info行:(NSInteger)row dropOperation:(nsttableview dropOperation)操作{
NSPasteboard*pboard=[info draggingPasteboard];
NSData*rowData=[pboard dataForType:MyPrivateTableViewDataType];
NSIndexSet*rowIndexes=[nsKeyedUnarchiveObjectWithData:rowData];
NSInteger-dragRow=[rowIndexes-firstIndex];
如果(dragRow<行){
[model insertObject:[model objectAtIndex:dragRow]atIndex:row];
[模型移除对象索引:dragRow];
[aTableView noteNumberOfRowsChanged];
[aTableView moverowatinex:dragRow-toIndex:row-1];
}否则{
ModelObj*obj=[model objectAtIndex:dragRow];
[模型移除对象索引:dragRow];
[模型插入对象:对象索引:行];
[aTableView noteNumberOfRowsChanged];
[aTableView moverowatinex:dragRow to index:row];
}
返回YES;
}

对数据源重新排序,并告诉tableview重新绘制。这一点我很清楚-我的问题是实际拖动以重新排序。在iOS上,这已经实现并自动发生。我想为NSTableView重现一个类似的行为,即单击并按住,然后将行拖动到新位置。在OSX下,它更通用,因为它用于拖放(即,您可以允许将文件从Finder拖动到tableview)。查看
NSTableView
类参考的部分。可能重复:谢谢,通过@ElTomato链接找到了一个简单的解决方案。我正在发布我的易于复制的代码作为这个问题的解决方案。从这里复制@optz这对我来说非常有效——节省了我大量的时间!谢谢你发帖!注意:我尝试使用NSTableViewDraggingDestinationFeedbackStyleGap,它在从下向上拖动时无法正常工作——它不会为第二行到下一行创建间隙,导致在拖动时套印移动的行文本。从顶部向下拖动确实有效。我回到了NstableViewDragingDestinationFeedback。