以编程方式绑定一个 NSTableView
Posted
技术标签:
【中文标题】以编程方式绑定一个 NSTableView【英文标题】:Programmatically bind a NSTableView 【发布时间】:2013-04-25 20:36:24 【问题描述】:我试图更好地了解可可绑定。我可以在 IB builder 中获得一个使用 NSArrayController 的基本表。我正在使用同一个项目并尝试以编程方式连接绑定,但是没有出现任何行。
这是我的头文件
@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;
关于我缺少哪一步有什么建议吗?
【问题讨论】:
【参考方案1】:简单的事情第一:确保 -awakeFromNib
只被调用一次,并且 _gdcManagedObjectContext
和 accountTable
在那时不是零。
尝试在视图中添加静态标签或背景颜色,以便确认问题是没有行(相对于行有不可见的内容)。 p>
当您确认问题是没有行时,您可以断定-awakeFromNib
中存在问题。尝试添加阵列控制器arrangedObjects
的打印输出。应该是空的。 -tableView:viewForTableColumn:row
中的代码理论上尚未被调用。您可以通过断点或 NSLog 来确认。
如果是这种情况,请检查您设置核心数据堆栈的位置。你在使用 NSPersistentDocument 吗?我遇到了一个问题,运行循环需要在托管对象上下文开始工作之前运行一次,但我必须考虑这是否是您在此处看到的问题。
-tableView:viewForTableColumn:row
中的代码存在问题,即您可能会一遍又一遍地设置绑定。您应该对单元格视图的每个实例执行一次。即使您想在代码中设置数组控制器,我建议您考虑在 nib 中绑定单元格视图的子视图,因为它就在那里。或者,如果您在代码中执行此操作,您需要找到一种方法在每个视图中执行一次。不过,我认为这不会导致您的问题。
风格要点:在您的代码中,使用self.accountArrayController
和self.gdcManagedObjectContext
而不是_accountArrayController
和_gdcManagedObjectContext
。此外,您可以将常量用于其他绑定类型:NSContentBinding
和 NSSelectionIndexesBinding
。
【讨论】:
【参考方案2】:感谢 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]);
【讨论】:
我已经以这种方式工作了。不,我想知道 arrayController 中包含的对象必须支持/符合什么。我在那里有NSManagedObject
s,tableView 显示行但不显示值...以上是关于以编程方式绑定一个 NSTableView的主要内容,如果未能解决你的问题,请参考以下文章