2012-02-04 52 views
16

當我從NSTableView中選擇一行時,它不會運行tableViewSelectionDidChange方法中的代碼。我已經在這個方法中設置了斷點,它甚至沒有進入該方法。如何通過從NSTableView中選擇一行來創建操作

任何想法?我在我的初始化程序中錯過了什麼嗎?

PersonController.h

#import <Foundation/Foundation.h> 

@interface Person : NSObject { 
    IBOutlet NSTableView *personsTable; 
    NSMutableArray *personsList; 
    NSMutableArray *personCollection; 

    IBOutlet NSTextField *selectedPersonName; 
    IBOutlet NSTextField *selectedPersonGender; 
@private 

} 

- (void)tableViewSelectionDidChange:(NSNotification *)aNotification; 

@end 

PersonController.m

#import "PersonController.h" 
#import "Person.h" 


@implementation PersonController 

- (id)init 
{ 
    self = [super init]; 
    if (self) { 
     personsList = [[NSMutableArray alloc] init]; 
     Person *person = [[Person alloc] init]; 

     // Create person 1 
     person.name = @"Bob"; 
     person.gender = @"male"; 

     // Append to array 
     [personsList addObject:person]; 
     [person release]; 

     // Create person 2 
     person = [[Person alloc] init]; 
     person.name = @"Fred"; 
     person.gender = @"Unknown"; 

     // Append to array 
     [personsList addObject:person]; 
     [person release]; 

     [personsTable reloadData]; 
    } 

    return self; 
} 

- (NSInteger)numberOfRowsInTableView:(NSTableView *)tableView { 
    return [personsList count]; 
} 

- (id)tableView:(NSTableView *)tableView objectValueForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row { 
    Person *person = [personsList objectAtIndex:row]; 
    NSString *identifier = [tableColumn identifier]; 

    return [person valueForKey:identifier]; 
} 

- (void)tableViewSelectionDidChange:(NSNotification *)aNotification 
{ 
    NSInteger selectedRow = [personsTable selectedRow]; 
    if (selectedRow == -1) 
    { 
     // these should be localized, but use string constants here for clarity 
     [selectedPersonName setStringValue:@"No selection"]; 
     [selectedPersonGender setStringValue:@"No selection"]; 
    } 
    else 
    { 
     Person *selectedPerson = [personCollection objectAtIndex:selectedRow]; 

     [selectedPersonName setStringValue:[selectedPerson name]]; 
     [selectedPersonGender setStringValue:[selectedPerson gender]]; 
    } 
} 

- (void)dealloc 
{ 
    [super dealloc]; 
} 

@end 
+0

我相信tableViewSelectionDidChange沒有被調用,因爲你沒有設置你的NSTableView的的委託。 – 2013-06-09 19:20:39

回答

27

所以這裏的問題是我試圖使用tableViewSelectionChange來觸發一個事件,當點擊NSTableColumn中的一行時。由於我無法得到這個工作,我採取了另一種方法,創建一個IBAction並將其鏈接到NSTableView,我發現這個工作正常。

爲了做到這一點,我做了以下內容:

  1. 刪除- (void)tableViewSelectionDidChange
  2. 創建IBAction爲
  3. 在XIB文件,創建IBAction爲和NSTableView的之間的Received Actions鏈接,在NSTableView的連接「發送的動作」下的檢查員具有「選擇器」動作「將該」選擇器「連接到要觸發的IBAction上

在PersonController.m

- (IBAction)columnChangeSelected:(id)sender 
{ 
    NSInteger selectedRow = [personsTable selectedRow]; 

    if (selectedRow != -1) { 
     NSLog(@"Do something with selectedRow!"); 
    } 
    else { 
     // No row was selected 
    } 
} 
2

確保PersonController的實例連接到personsTable爲代表。我不知道你是如何創建NSTableView的,但是如果你使用的是Nib,你可以在Interface Builder中設置委託。如果不是,則可以在初始方法中添加[personsTable setDelgate:self]並且在dealloc方法中添加[personsTable setDelegate:nil]

另外,你是泄漏 personsList。將[personsList release]添加到您的委託方法。

+0

PersonController的實例已作爲委託連接到personsTable。儘管感謝您發現personsList泄漏。 – Coderama 2012-02-04 15:10:41

2

的IBAction爲對於其他人誰碰到這個問題:其他原因沒有委託被稱爲可能是因爲該行已被選中。所以它不會通知,除非有新的選擇。如果您仍然希望能夠在每次點擊時收到通知,請在收到通知後取消選擇所有行。

現在,這將打2個電話給您的代表,一個用於選擇和其他取消選擇。不需要第二次調用,因此在頂部添加條件以檢查[tableView selectedRow],如果未選擇行,這將返回-1

3

要在Coderama的回答擴大,代碼可等效爲:

tableView.target = self; 
tableView.action = @selector(tableViewClicked:); 

然後實現在同一個類中的方法:

- (void)tableViewClicked:(id)sender { 
    // This will return -1 if the click did not land on a row 
    NSLog(@"tableView.clickedRow = %ld", tableView.clickedRow); 

    // This will return -1 if there is no row selected. 
    NSLog(@"tableView.selectedRow = %ld", tableView.selectedRow); 
} 

表視圖會調用它的操作方法對目標每次點擊視圖時都會設置。這會讓你知道每次選擇一行,即使它已經被選中。在斯威夫特3

1

解決方案對於大部分事件:

裏面的tableview視圖控制器:

override func viewDidLoad() { 
    super.viewDidLoad() 

    tableView.target = self 
    tableView.action = #selector(tableViewDidClick) 
} 

func tableViewDidClick(){ 
    let row = tableView.clickedRow 
    let column = tableView.clickedColumn 
    let unselected = -1 

    if row == unselected && column == unselected{ 
     tableViewDidDeselectRow() 
     return 
    }else if row != unselected && column != unselected{ 
     tableViewDidSelectRow(row) 
     return 
    }else if column != unselected && row == unselected{ 
     tableviewDidSelectHeader(column) 
    } 
} 

private func tableViewDidDeselectRow() { 
    // clicked outside row 
} 

private func tableViewDidSelectRow(_ row : Int){ 
    // row did select 
} 

private func tableviewDidSelectHeader(_ column : Int){ 
    // header did select 
} 
相關問題