2012-02-04 7 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

は、呼び出されていませんでした。 –

答えて

27

ここで問題は、NSTableColumnの行がクリックされたときにtableViewSelectionChangeを使用してイベントをトリガーしようとしていたことです。私はこの作業を得ることができませんでしたので、私はIBActionを作成し、これをNSTableViewにリンクする別のアプローチをとっており、これがうまくいくことがわかりました。これを行うために

、私は次のようでした:

  1. - (void)tableViewSelectionDidChange
  2. NSTableView接続で、IBActionとNSTableViewの間Received Actionsリンクを作成し、XIBファイルでIBAction
  3. の作成を削除します。 「送信アクション」のインスペクタに「セレクタ」アクションがあります。このセレクタをトリガーしたいIBActionに接続してください。

これは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を作成したのかわかりませんが、Nibsを使用している場合はInterface Builderでデリゲートを設定できます。そうでない場合は、メソッドで[personsTable setDelgate:self]を追加し、deallocメソッドで[personsTable setDelegate:nil]を追加することができます。

personsListもあります。デリゲートメソッドに[personsList release]を追加します。

+0

PersonControllerのインスタンスは、すでにdelegatesとしてpersonsTableに接続されています。しかし、PersonListListを見つけてくれてありがとう。 – Coderama

2

です:行がすでに選択されているため、このデリゲートが呼び出されていないため、他の理由がある可能性があります。したがって、新しい選択が行われない限り通知されません。まだすべての行の通知を受け取ることができるようにするには、通知を受け取ったすべての行を選択解除します。

これで、デリゲートを2回コールします.1つは選択され、もう1つは選択解除されます。 2番目の呼び出しが不要なので、上に条件を追加して[tableView selectedRow]を確認します。行が選択されていない場合は-1が返されます。Coderamaの答えに拡大すること

3

、コードの等価です:

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

ソリューション:

テーブルビュー内のビューコントローラ:あなたはNSTableViewのデリゲートを設定していなかったので、私はtableViewSelectionDidChangeを信じる

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 
} 
関連する問題