为NSOutlineView创建一个Controller

时间:2012-11-20 17:24:04

标签: objective-c macos cocoa nsoutlineview

我遇到了为我所拥有的NSOutlineView创建单独的Controller类的问题。

我创建了一个名为LTSidebarViewController的新类,在我的MainMenu.xib文件中,我向'workbench'添加了一个Object,并将其链接到我的LTSidebarViewController类。我还将委托和数据源设置为链接到MainMenu.xib中的NSOutlineView。

我要做的是从我的AppDelegate文件中的- (void)applicationDidFinishLaunching:(NSNotification *)aNotification内创建此类的实例,当我这样做时,我想传入App Delegate的managedObjectContext。所以,我在init中创建了一个自定义LTSidebarViewController方法,如下所示:

-(id)initWithManagedObject:(NSManagedObjectContext*)managedObject{

    self = [super init];
    if (self) {
        self.managedObjectContext = managedObject;

        NSFetchRequest *subjectsFetchReq = [[NSFetchRequest alloc]init];
        [subjectsFetchReq setEntity:[NSEntityDescription entityForName:@"Subject"
                                                inManagedObjectContext:self.managedObjectContext]];

        subjectsArray = [self.managedObjectContext executeFetchRequest:subjectsFetchReq error:nil];

        _topLevelItems = [NSArray arrayWithObjects:@"SUBJECTS", nil];

        // The data is stored in a  dictionary
        _childrenDictionary = [NSMutableDictionary new];
        [_childrenDictionary setObject:subjectsArray forKey:@"SUBJECTS"];

        // The basic recipe for a sidebar
        [_sidebarOutlineView sizeLastColumnToFit];
        [_sidebarOutlineView reloadData];
        [_sidebarOutlineView setFloatsGroupRows:NO];

        // Set the row size of the tableview
        [_sidebarOutlineView setRowSizeStyle:NSTableViewRowSizeStyleLarge];

        // Expand all the root items; disable the expansion animation that normally happens
        [NSAnimationContext beginGrouping];
        [[NSAnimationContext currentContext] setDuration:0];
        [_sidebarOutlineView expandItem:nil expandChildren:YES];
        [NSAnimationContext endGrouping];

        // Automatically select first row
        [_sidebarOutlineView selectRowIndexes:[NSIndexSet indexSetWithIndex:1] byExtendingSelection:NO];
    }
    return self;

}

我也有这个课程中所有必需的方法,- (NSView *)outlineView:(NSOutlineView *)outlineView viewForTableColumn:(NSTableColumn *)tableColumn item:(id)item等。

在App Delegate中的- (void)applicationDidFinishLaunching:(NSNotification *)aNotification方法内,我有以下内容:

    LTSidebarViewController *sidebarViewController = [[LTSidebarViewController alloc] initWithManagedObject:self.managedObjectContext];

我的问题是这不起作用,我没有收到任何错误,应用程序运行但NSOutlineView中没有显示数据。

现在从我能说的问题是,当MainMenu.xib文件最初加载时,它会自动创建我的LTSidebarViewController类的实例并调用它的init方法,但因为我的init方法没有应用程序没有正确启动的任何内容。

我在这里采取了正确的方法吗?简单来说,我正在寻找的是一个单独的文件,用作我的NSOutlineView的数据源。

1 个答案:

答案 0 :(得分:1)

使用NSOutlineView时,我通常会进行大量的日志记录,以确定发生了什么。我可能会做类似以下的事情(也许你已经做了一些):

通过记录来确保您在subjectArray中确实拥有数据,例如

NSLog(@"subjectsArray");
NSLog(@"%@", subjectsArray);

确保您已在AppDelegate.m文件中的NSOutlineView Datasource Methods中实施了NSOutlineView数据源协议方法,并且他们正在返回相应的数据。

  • 如果您需要帮助来实现这些,请尝试使用Source Lists and NSOutlineView等教程。

  • 我通常会在每个NSOutlineView数据源方法中使用NSLog语句,以确保它们被调用,并且我理解每个人期望和返回的内容。

通过记录它们,确保您的initWithManagedObject:(NSManagedObjectContext *)managedObject方法中的委托和数据源由于某种原因不是零,例如

NSLog(@"datasource: %@", [self datasource]);
NSLog(@"delegate: %@", [self delegate]);

如果您发现由于某种原因它们是零,您可以手动设置它们以确保不是问题,例如在initWithManagedObject中:

[self setDelegate: [NSApp delegate]];
[self setDatasource: [NSApp delegate]];

至于这是否是“正确的”方法:我不清楚你的代码是否打算sideBarController既是delegate又是datasource或是否{ {1}}正在为这些角色提供服务。显然,您需要在相应的文件中实现AppDelegatedelegate协议。你确定可以datasource为这些角色提供服务,尽管让sideBarController更有意义。

小注意事项:我有时会直接从支持文件中访问AppDelegate的managedObjectContext,例如

AppDelegate

而不是手动将managedObjectContext传递给每个文件。