2013-04-25 100 views
2

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

这是我的头文件

@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; 
} 

上是缺少了哪一步我有什么建议?

+0

嘿,欢迎来到SO! – paulmelnikow 2013-04-25 21:05:27

回答

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]); 
    } 
} 
+0

我有这种方式工作。我不知道arrayController中包含的对象必须支持/符合什么。我有'NSManagedObject'在那里和tableView显示行,但不显示值... – 2014-06-23 16:27:53

3

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

尝试添加静态标签或背景颜色到您的视图,以便您可以确认问题是没有行(与行与无形的内容)。

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

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

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

文体要点:在您的代码中,请使用self.accountArrayControllerself.gdcManagedObjectContext而不是_accountArrayController_gdcManagedObjectContext。另外,您可以使用其他绑定类型的常量:NSContentBindingNSSelectionIndexesBinding

相关问题