2011-05-10 85 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; 
}