代码之家  ›  专栏  ›  技术社区  ›  Ellie P.

如何使用核心数据和抽象实体创建主-细节界面?

  •  2
  • Ellie P.  · 技术社区  · 16 年前

    苹果有一个很好的小教程来制作一个简单的主细节界面。Interface Builder甚至会从核心数据实体自动为您生成一个。然而,我正在尝试做一些比这个简单的例子更复杂的事情,我已经努力了一段时间让它工作。

    我希望该界面允许用户查看主列表(NSTableView)中所有类型的页面。当他们选择一个页面时,显示的详细信息字段将取决于该页面的类型。

    以下是我现在拥有的:

    我有一个主nib文件,其中显示主列表,以及一个页面共有的所有字段。每个页面类型都有一个nib及其特定字段。主nib文件中有一个主NSArrayController,它正在填充NSTableView。每个页面特定的NIB中都有一个NSArrayController,这样我就可以将细节字段绑定到当前选择的属性。我所有的NSArrayController都配置相同,并且我将它们都绑定到相同的managedObjectContext和相同的SelectionIndex。

    我正在使用Aaron Hillegass在其Cocoa书中描述的视图交换方法。因此,我注册了NSTableViewSelectionDidChangeNotifications,当我收到一个通知时,它会调用一个方法switchView:

    switchView查看当前选定的对象,检查它是哪种类型的页面,并根据Hillegass的方法交换相应的nib文件。

    如果只添加一种类型的页面,一切正常,但一旦添加第二种类型的页面,就会出现以下错误:

    为对象的键路径选择索引设置值时出错(来自绑定对象实体:页,所选对象数:1):[valueForUndefinedKey:]:实体NoColPage不符合键端的键值编码。

    错误的最后一部分是有意义的:它试图显示错误的nib,因此它试图绑定到该对象不存在的字段。

    我在我的文档中添加了一个SelectionIndex字段,这样我的所有NSArrayController都可以绑定到同一个位置。我为这件事苦恼了好几天,但我想不出来。有什么想法吗?

    如果有帮助的话, here is a sample project you can download

    编辑: 我想约书亚知道了一些事情,但不幸的是,它不起作用——我一直遇到同样的问题。起初我很难理解-unbind:需要一个字符串常量,而不是键路径。

    我尝试了几种变体:跟踪当前显示的nib的阵列控制器;其中,我跟踪当前显示的页面类型,并且仅在尝试显示其他页面类型时取消绑定/重新绑定。。。

    下面是代码的相关部分。

    -(void) displayViewController: (ManagingVC *) vc withClass:(NSString*) className {
    
    //Try to end editing
    NSWindow *w = [box window];
    BOOL ended = [w makeFirstResponder:w];
    if (!ended) {
        NSBeep();
        return;
    }
    
    //The Managing View Controller's NSArrayController
    NSArrayController* vcAc = [vc arrCont];
    
    //if the page we're trying to switch to is NOT the same type as the current page we're displaying
    //if it is, do nothing.
    if (![currPageDisplayed isEqual:className]) {
    
        //unbind the old view controller
        ManagingVC *oldvc = [viewControllers objectForKey:className];
        NSArrayController* oldsac = [oldvc arrCont];
        [oldsac unbind:@"selectionIndexes"];
    
        //bind the new view controller
        [vcAc bind:@"selectionIndexes" toObject:self withKeyPath:@"selectionIndexes" options:nil];
        currPageDisplayed = className;
    
        NSView *v = [vc view];
    
        //display the new view in an NSBox in the main nib
        [box setContentView:v];
    }
    

    }

    2 回复  |  直到 16 年前
        1
  •  1
  •   Joshua Nozzi    16 年前

    试试这个:

    1. 移除NIB中的绑定。
    2. 在添加新视图之前,请在代码中连接其绑定。
    3. 删除旧视图之前,请在代码中断开其绑定。

    这应该让一切都开心。

        2
  •  0
  •   Ellie P.    16 年前

    在花了太多时间试图使每个NIB的阵列控制器同步后,我放弃了这种方法。对我来说唯一有效的方法就是通过编程控制在主nib中显示哪些GUI元素及其绑定。这意味着消除其他笔尖。如果您处理的不仅仅是几个文本字段,那么这并不是一个可持续的解决方案,但它现在对我很有效。