如何通过NSArrayController从Core Data填充NSTableView?

时间:2012-08-28 06:09:22

标签: objective-c core-data nstableview nsarraycontroller

最初我通过插座填充我的NSTableView并将表的dataSource设置为我的控制器类。我正在尝试切换到使用NSArrayController,以便我可以在我的应用程序中按列进行排序。

在IB中,我添加了一个Array Controller对象。我将Sort Descriptors绑定连接到共享用户默认值控制器,以便可以在我的应用程序启动之间保留已排序的列。我将表的每一列绑定到Array Controller,控制器键设置为'arrangeObjects',Model Key Path设置为应该呈现的字段的名称。

我的数据来自Core Data,我试图显示的实体与另一个实体有关系。第二个实体上的属性需要显示为其中一个表列的值。任何人对我在这里缺少的东西都有任何想法/建议吗?

MainWindowController.h

#import <Cocoa/Cocoa.h>
#import "Notification.h"

@class AppDelegate;

@interface MainWindowController : NSWindowController <NSTableViewDataSource, NSTableViewDelegate> {
    AppDelegate <NSApplicationDelegate> *appDelegate;
}

//@property NSMutableArray *userNotifications;

@property (weak) IBOutlet NSTableView *notificationsTable;
@property (weak) IBOutlet NSArrayController *notificationsController;

@end

MainWindowController.m

#import "AppDelegate.h"
#import "MainWindowController.h"
#import "Utils.h"

@implementation MainWindowController

//@synthesize userNotifications;

@synthesize notificationsTable;
@synthesize notificationsController;

- (void) doubleClick:(id)sender
{
    NSInteger row = [notificationsTable clickedRow];

//  Notification *clickedNotification = [userNotifications objectAtIndex:row];
//  Notification *clickedNotification = 

//  [appDelegate redirectToBrowser:clickedNotification];
}

- (id) initWithWindowNibName:(NSString *)windowNibName
{
    self = [super initWithWindowNibName:windowNibName];
    if (self) {
//      userNotifications = [[NSMutableArray alloc] init];
        appDelegate = (AppDelegate *) [[NSApplication sharedApplication] delegate];
        [notificationsController setManagedObjectContext:[appDelegate managedObjectContext]];
        [notificationsController setEntityName:@"Notification"];
        [notificationsController setAutomaticallyPreparesContent:YES];

        [notificationsController fetch:self];
        [notificationsTable reloadData];
    }
    return self;
}

- (void)windowDidLoad
{
    [super windowDidLoad];

    // Implement this method to handle any initialization after your window controller's window has been loaded from its nib file.

    [notificationsTable reloadData];
}

- (void)awakeFromNib
{
    [notificationsTable setTarget:self];
    [notificationsTable setDoubleAction:@selector(doubleClick:)];
}

1 个答案:

答案 0 :(得分:1)

此问题有两种解决方案:

  1. 通过添加新对象并将类设置为 AppDelegate ,将App Delegate对象添加到IB。
  2. 通过将以下代码添加到.h和.m文件中,将App Delegate指定为呈现窗口的控制器的实例变量 appDelegate
  3. 或者Controller.h

    @class AppDelegate;
    
    @interface Controller : NSWindowController {
        AppDelegate <NSApplicationDelegate> *appDelegate;
    }
    

    Controller.m或者

    #import "AppDelegate.h"
    
    - (id) initWithWindowNibName:(NSString *)windowNibName
    {
        self = [super initWithWindowNibName:windowNibName];
        if (self) {
            appDelegate = (AppDelegate *) [[NSApplication sharedApplication] delegate];
        }
        return self;
    }
    

    在任何一种情况下,您都需要为Array Controller添加新的绑定。导航到Inspector中的Binding窗格,并将Managed Object Context(在Parameters下)绑定到(1)App Delegate或(2)File的所有者,然后将Model Key Path设置为(1)self .managedObjectContext或(2)self.appDelegate.managedObjectContext