简体   繁体   English

在NSTableView中实现拖放

[英]Implementing drag and drop in NSTableView

Can anyone help me to implement drag and drop in an NSTableView? 任何人都可以帮我在NSTableView中实现拖放操作吗? I used this code below, but these methods are not getting called during execution. 我在下面使用了这段代码,但这些方法在执行期间没有被调用。

- (BOOL)tableView:(NSTableView *)tv writeRowsWithIndexes:(NSIndexSet *)rowIndexes toPasteboard:(NSPasteboard*)pboard
{
    // Copy the row numbers to the pasteboard.
    NSData *data = [NSKeyedArchiver archivedDataWithRootObject:rowIndexes];
    [pboard declareTypes:[NSArray arrayWithObject:@".gif"] owner:self];
    [pboard setData:data forType:@".gif"];
    return YES;
}

- (NSDragOperation)tableView:(NSTableView*)tv validateDrop:(id <NSDraggingInfo>)info proposedRow:(NSInteger)row proposedDropOperation:(NSTableViewDropOperation)op
{
    // Add code here to validate the drop

    if (row > [ m_imageArray count])
        return NSDragOperationNone;

    if (nil == [info draggingSource]) // From other application
    {
        return NSDragOperationNone;
    }
    else if (self == [info draggingSource]) // From self
    {
        return NSDragOperationNone;
    }
    else // From other documents 
    {
        [tv setDropRow: row dropOperation: NSTableViewDropAbove];
        return NSDragOperationCopy;
    }

    NSLog(@"validate Drop");
    return NSDragOperationCopy;
}


- (BOOL)tableView:(NSTableView *)aTableView acceptDrop:(id <NSDraggingInfo>)info
              row:(NSInteger)row dropOperation:(NSTableViewDropOperation)operation
{
    NSPasteboard* pboard = [info draggingPasteboard];
    NSData* rowData = [pboard dataForType:@".gif"];
    NSIndexSet* rowIndexes = [NSKeyedUnarchiver unarchiveObjectWithData:rowData];
    NSInteger dragRow = [rowIndexes firstIndex];

    // Move the specified row to its new location...
}

Here is an example 这是一个例子

#import "TableViewController.h"
#import "Person.h"

#define MyDataType @"MyDataType"

@implementation TableViewController {
    NSMutableArray *list;
    NSInteger sourceIndex;
}
@synthesize tableView;

-(void)awakeFromNib {
    [tableView registerForDraggedTypes:[NSArray arrayWithObjects:MyDataType, nil]];
    list = [[NSMutableArray alloc] init];
    Person *person = [[Person alloc] initWithName:@"Newton" age:64];
    [list addObject:person];
    person = [[Person alloc] initWithName:@"Archimedes" age:74];
    [list addObject:person];
    person = [[Person alloc] initWithName:@"Euler" age:44];
    [list addObject:person];
    person = [[Person alloc] initWithName:@"Poincare" age:24];
    [list addObject:person];
    person = [[Person alloc] initWithName:@"Gauss" age:34];
    [list addObject:person];
}

-(void)reArrange:(NSMutableArray *)array sourceNum:(NSInteger)sourceNum destNum:(NSInteger)destNum {
    Person *person = list[sourceNum];
    [list insertObject:person atIndex:destNum];

    if (sourceNum < destNum) {
        [list removeObjectAtIndex:sourceNum];
    } else {
        [list removeObjectAtIndex:sourceNum+1];
    }

    [tableView reloadData];
}


#pragma mark - Table

// how many rows are there in the table?
-(NSInteger)numberOfRowsInTableView:(NSTableView *)tv {
    return list.count;
}

// What object should I show in a particular cell?
-(id)tableView:(NSTableView *)tv objectValueForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row {
    Person *person = list[row];
    NSString *identifier = [tableColumn identifier];
    return [person valueForKey:identifier];
}

// Should I accept the drag with the rows specified by rowIndexes? If YES then place the data on the provided paste board.
- (BOOL)tableView:(NSTableView *)tv writeRowsWithIndexes:(NSIndexSet *)rowIndexes toPasteboard:(NSPasteboard *)pboard {
    NSData *data = [NSKeyedArchiver archivedDataWithRootObject:rowIndexes];
    [pboard declareTypes:[NSArray arrayWithObject:MyDataType] owner:self];
    [pboard setData:data forType:MyDataType];
    sourceIndex = [rowIndexes firstIndex];
    return YES;
}

// What kind of drag operation should I perform?
- (NSDragOperation)tableView:(NSTableView*)tv validateDrop:(id )info proposedRow:(NSInteger)row proposedDropOperation:(NSTableViewDropOperation)op {
    return op == NSTableViewDropAbove; // Specifies that the drop should occur above the specified row.
}

// The mouse button was released over a row in the table view, should I accept the drop?
- (BOOL)tableView:(NSTableView*)tv acceptDrop:(id )info row:(NSInteger)row dropOperation:(NSTableViewDropOperation)op {
    [self reArrange:list sourceNum:sourceIndex destNum:row]; // let the source array reflect the change
    return YES;
}

@end

You need to declare a custom drag type for your table view and then call registerForDraggedTypes: with your custom type. 您需要为表视图声明自定义拖动类型,然后使用您的自定义类型调用registerForDraggedTypes: . Otherwise, as you have noticed, none of these methods will get called. 否则,正如您所注意到的,这些方法都不会被调用。

当我忘记将dataSource到IB中的NSTabeView时,我通常会观察到这种错误,即实现tableView:writeRowsWithIndexes:toPasteboard:的类tableView:writeRowsWithIndexes:toPasteboard: NSTableViewDataSource的方法。

Drag and Drop NSTableview using core data 使用核心数据拖放NSTableview

  1. Register table-view object for drag and drop:- 注册用于拖放的表视图对象: -

     [tblCategory registerForDraggedTypes:[NSArray arrayWithObject:@"public.text"]]; 

Drag and drop Delegate methods:- 拖放委托方法: -

 - (id <NSPasteboardWriting>)tableView:(NSTableView *)tableView pasteboardWriterForRow:(NSInteger)row
 {

 Category *category = (Category *)[self.arrCategoryList objectAtIndex:row];
 NSString *identifier = category.categoryname;

 NSPasteboardItem *pboardItem = [[NSPasteboardItem alloc] init];
 [pboardItem setString:identifier forType: @"public.text"];
 return pboardItem;
 }

 - (NSDragOperation)tableView:(NSTableView *)tableView validateDrop:(id <NSDraggingInfo>)info proposedRow:(NSInteger)row proposedDropOperation:(NSTableViewDropOperation)dropOperation
{


if(dropOperation == NSTableViewDropOn)
{
NSPasteboard *p = [info draggingPasteboard];
NSString *title = [p stringForType:@"public.text"];
Category* category ;
NSInteger srcIndex;
for (srcIndex = 0; srcIndex < [_arrCategoryList count]; srcIndex++)
{
  category = [_arrCategoryList objectAtIndex:srcIndex];
if ([category.categoryname isEqualToString:title])
{
        break;
}
    category = nil;
}
if(!category)
{
     // Not found
     return NO;
 }

 [_arrCategoryList removeObjectAtIndex:srcIndex];
 [_arrCategoryList insertObject:category atIndex:row];
 [tblCategory reloadData];
 return NSDragOperationMove;
}
  return NSDragOperationNone;
}

 - (BOOL)tableView:(NSTableView *)tableView acceptDrop:(id <NSDraggingInfo>)info row:(NSInteger)row dropOperation:(NSTableViewDropOperation)dropOperation
 {
   return YES;
}

您可以为NSMutableArray或NSMutableDictionary或任何其他对象注册draggedTypes。以下代码片段用于NSMutableArray。

[tableView registerForDraggedTypes:[NSArray arrayWithObject:@"NSMutableArray"] ];

You need to declare a registerForDraggedTypes method in awakFromnib 您需要在awakFromnib声明registerForDraggedTypes方法

like this. 像这样。

[table_view registerForDraggedTypes:[NSArray arrayWithObjects:BasicTableViewDragAndDropDataType, nil]];

I have to recommend both this excellent Red Sweater blog post 我必须推荐这个优秀的红毛衣博客文章

http://www.red-sweater.com/blog/274/a-moveable-beast http://www.red-sweater.com/blog/274/a-moveable-beast

It provides an NSArrayController sub-class which will enable drag and drop re-ordering of table items, and if you want to support dragging outside of the tableview with your objects, we've just written up a neat and simple addition to that class: 它提供了一个NSArrayController子类,它将支持对表项进行拖放重新排序,如果你想支持在tableview外部拖动你的对象,我们只需要为该类编写一个简洁的简单添加:

http://www.rwe-uk.com/blog/comments/nstableview_drag_and_drop_with_bindings_and_nsarraycontroller http://www.rwe-uk.com/blog/comments/nstableview_drag_and_drop_with_bindings_and_nsarraycontroller

It builds on the original post 它建立在原始帖子的基础上

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM