最初は空である必要があるビューベースの NSTableView があります。同じ NSTableView から行を追加および削除するための「追加」および「削除」ボタンもあります。
新しい行を追加するための私のデリゲート メソッドとメソッドは次のようになります。
#import "PreferencesApiKeysViewController.h"
#import "UserKeys.h"
@interface PreferencesApiKeysViewController ()
@property (weak) IBOutlet NSTableView *keysTableView;
@end
@implementation PreferencesApiKeysViewController
- (NSView *)tableView:(NSTableView *)tableView viewForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row {
// Get a new ViewCell
NSTableCellView *cellView = [tableView makeViewWithIdentifier:tableColumn.identifier owner:self];
if([tableColumn.identifier isEqualToString:@"userKeysColumn"]) {
UserKeys *allKeys = [self.allKeys objectAtIndex:row];
cellView.textField.stringValue = allKeys.userKeyName;
return cellView;
}
return cellView;
}
- (NSInteger)numberOfRowsInTableView:(NSTableView *)tableView {
NSLog(@"Initial rows: %li", (unsigned long)[self.allKeys count]);
return [self.allKeys count];
}
- (IBAction)addKey:(id)sender {
UserKeys *newKey = [[UserKeys alloc] initWithKeyName:@""
apiID:@""
apiCode:@"" ];
[self.allKeys addObject:newKey];
NSLog(@"Total rows: %li", (unsigned long)self.allKeys.count);
NSInteger newRowIndex = self.allKeys.count;
if (newRowIndex == 0) {
NSLog(@"No rows.");
newRowIndex = 0;
} else {
NSLog(@"Has rows.");
newRowIndex = self.allKeys.count-1;
}
NSLog(@"New Index: %ld", (long)newRowIndex);
[self.keysTableView insertRowsAtIndexes:[NSIndexSet indexSetWithIndex:newRowIndex] withAnimation:NSTableViewAnimationSlideDown];
[self.keysTableView selectRowIndexes:[NSIndexSet indexSetWithIndex:newRowIndex] byExtendingSelection:NO];
[self.keysTableView scrollRowToVisible:newRowIndex];
}
@end
私の AppDelegate.m では、次のようにビューを呼び出しています。
#import "AppDelegate.h"
#import "UserKeys.h"
#include "PreferencesApiKeysViewController.h"
@interface AppDelegate()
@property (nonatomic,strong) IBOutlet PreferencesApiKeysViewController *prefsViewController;
@end
@implementation AppDelegate
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
self.prefsViewController = [[PreferencesApiKeysViewController alloc] initWithNibName:@"PreferencesApiKeysViewController" bundle:nil];
// Create few rows as dummy data
/*
UserKeys *key1 = [[UserKeys alloc] initWithKeyName:@"key one"
apiID:@"123"
apiCode:@"xxx" ];
UserKeys *key2 = [[UserKeys alloc] initWithKeyName:@"key two"
apiID:@"456"
apiCode:@"yyy" ];
NSMutableArray *tempKeys = [NSMutableArray arrayWithObjects:key1, key2, nil];
self.prefsViewController.allKeys = tempKeys;
*/
// done.
[self.window.contentView addSubview:self.prefsViewController.view];
self.prefsViewController.view.frame = ((NSView*)self.window.contentView).bounds;
}
@end
ここで重要なのは、AppDelegate にダミー データを追加するための数行のコメントを外してアプリを起動すると、すべて正常に動作するということです。問題なく行を追加/削除できます。すべての行を削除して、その後新しい行を追加することもできます。
しかし、これらの行を再度コメントすると、アプリは空のテーブル (必要なもの) で開始され、新しい行を追加しようとするとエラーが発生します。
*** Assertion failure in -[NSTextFieldCell _objectValue:forString:errorDescription:], /SourceCache/AppKit/AppKit-1187.34/AppKit.subproj/NSCell.m
スレッドをさらに見てみると、私のアプリを参照している行は 1 行だけです。
0x0000000100003116 -[PreferencesApiKeysViewController tableView:viewForTableColumn:row:] + 406
配列に単一のオブジェクトが実際に含まれていない場合、TableView が適切にインスタンス化されていないと推測していallKeys
ますが、それを修正する方法がわかりません。空の NSTableView を作成し、「追加」ボタンがクリックされたときに自分で最初の行を追加できるようにする方法 (ダミー データを追加せずにallKeys
)。