以编程方式绑定NSTableView

时间:2013-04-25 20:36:24

标签: cocoa core-data nstableview cocoa-bindings

我试图更好地理解可可绑定。我可以在IB构建器中使用NSArrayController获取基本表。我正在使用相同的项目并尝试以编程方式连接绑定,但是没有出现任何行。

这是我的Header文件

@interface SBGoalDetailController : NSViewController <NSTableViewDelegate, NSTableViewDataSource>

@property (nonatomic, strong) NSManagedObjectContext *gdcManagedObjectContext;
@property (nonatomic, strong) NSArrayController *accountArrayController;
@property (weak) IBOutlet NSTableView *accountTable;


- (id)initWithContext:(NSManagedObjectContext *)context;

我的实施档案

@implementation SBGoalDetailController

- (id)initWithContext:(NSManagedObjectContext *)context
{
    self = [super initWithNibName:@"GoalDetailView" bundle:nil];
    if (self) {
        [self setGdcManagedObjectContext:context];
    }
    return self;
}



- (void)awakeFromNib
{
    _accountArrayController = [[NSArrayController alloc] init];

    [[self accountArrayController] setManagedObjectContext:_gdcManagedObjectContext];
    [[self accountArrayController] setEntityName:@"Account"];
    [[self accountArrayController] setAutomaticallyPreparesContent:YES];
    [[self accountTable] bind:@"content" toObject:_accountArrayController withKeyPath:@"arrangedObjects" options:nil];

    [[self accountTable] bind:@"selectionIndexes" toObject:_accountArrayController withKeyPath:@"selectionIndexes" options:nil];
}


- (NSView *)tableView:(NSTableView *)tableView viewForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row
{

    NSView *returnView = [tableView makeViewWithIdentifier:@"AccountCell" owner:[tableView delegate]];

        NSTextField* textField = [[returnView subviews] objectAtIndex: 0];

    [textField bind: NSValueBinding
           toObject: returnView
        withKeyPath: @"objectValue.accountName"
            options: nil];

    return returnView;
}

关于我缺少哪一步的任何建议?

2 个答案:

答案 0 :(得分:3)

简单的事情:确保-awakeFromNib只被调用一次,_gdcManagedObjectContextaccountTable当时是非零。

尝试在视图中添加静态标签或背景颜色,以便确认问题是 no rows (与具有不可见内容的行相比)。

当您确认问题没有行时,您可以断定-awakeFromNib中存在问题。尝试添加阵列控制器arrangedObjects的打印输出。它可能是空的。理论上-tableView:viewForTableColumn:row中的代码尚未被调用。您可以使用断点或NSLog确认。

如果是这种情况,请检查您设置Core Data堆栈的位置。你在使用NSPersistentDocument吗?我遇到了一个问题,运行循环需要在托管对象上下文开始工作之前运行一次但是我必须考虑一下这是否是你在这里看到的问题。

-tableView:viewForTableColumn:row中的代码存在问题,即您可能会反复设置绑定。您应该为每个单元格视图实例执行一次此操作。即使你想在代码中设置数组控制器,我建议你考虑在nib中绑定单元格视图的子视图,因为它就可以了。或者,如果您在代码中执行此操作,则需要找到一种方法,每个视图只执行一次。不过,我不认为这会导致你的问题。

文体点:在您的代码中,使用self.accountArrayControllerself.gdcManagedObjectContext代替_accountArrayController_gdcManagedObjectContext。此外,您可以将常量用于其他绑定类型:NSContentBindingNSSelectionIndexesBinding

答案 1 :(得分:3)

感谢Noa,ArrayController的内容为零,然后我偶然发现了这一部分Automatically Prepares Content flag,还注意了你的风格点并将我的awakeFromNib更改为以下内容......所有似乎都在工作,谢谢。

- (void)awakeFromNib
{
    [self setAccountArrayController:[[NSArrayController alloc] init]];

    [[self accountArrayController] setManagedObjectContext:[self gdcManagedObjectContext]];
    [[self accountArrayController] setEntityName:@"Account"];

    NSError *error = nil;
    BOOL success = [[self accountArrayController] fetchWithRequest:nil merge:NO error:&error];
    if (success) {
        [[self accountTable] bind:NSContentBinding toObject:[self accountArrayController] withKeyPath:@"arrangedObjects" options:nil];

        [[self accountTable] bind:NSSelectionIndexesBinding toObject:[self accountArrayController] withKeyPath:@"selectionIndexes" options:nil];
    } else {
        NSLog(@"Error %@:", [error localizedDescription]);
    }
}