2011-05-10 132 views
3

任何人都可以帮助我在NSTableView中实现拖放操作吗?我在下面使用了这个代码,但是这些方法在执行期间没有被调用。在NSTableView中实现拖放操作

- (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... 
} 

回答

8

你需要声明一个自定义的拖类型的表视图,然后调用registerForDraggedTypes:您的自定义类型。否则,正如你所注意到的,这些方法都不会被调用。

+1

嗨,感谢您的建议。但我不知道如何声明自定义拖动式 – 2011-05-11 08:13:38

0

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

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

0

您需要awakFromnib

这样来声明registerForDraggedTypes方法。

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

我一定要推荐这两个这个优秀的红毛衣的博客文章

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

它提供了一个NSArrayController的子类,这将使拖放的表项重新排序,如果你想要支持拖动你的对象外的桌面视图,我们刚刚写了一个简洁而又简单的加入类:

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

它建立在原来的岗位

+0

链接损坏“网站错误:无法加载网站偏好设置;找不到首选项” – 2017-02-22 16:08:58

0

我通常观察到这种类型的错误,当我忘记了dataSource挂钩到IB的NSTabeView,即实现NSTableViewDataSourcetableView:writeRowsWithIndexes:toPasteboard:方法的类。

6

下面是一个例子

#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 
+0

此解决方案正常工作,谢谢! – Christophe 2015-12-27 13:30:34

+0

这是一个更全面的回应,谢谢你的时间。 – TheFuquan 2016-04-14 21:45:57

0

拖动并使用掉落NSTableView的核心数据

  1. 注册拖放表视图对象: -

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

拖放委托方法: -

- (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; 
}