如何使用Core Data和抽象实体创建主 - 详细信息界面?
-
06-07-2019 - |
题
Apple有一个很好的小教程,用于制作一个简单的主 - 细节界面。 Interface Builder甚至可以从Core Data实体自动为您生成一个。但是,我正在尝试做一些比简单例子更复杂的事情,而且我一直在努力让它发挥作用。
我有一个基于Core Data文档的应用程序。该模型包括一个抽象实体Page,以及Page的几个具体子实体。所有页面都有一些共同的属性(如“name”),这些属性在Page中定义。显然,子实体具有独特的属性。
我希望界面允许用户在主列表中查看所有类型的页面(NSTableView)。当他们选择一个页面时,显示的详细信息字段将取决于它是什么类型的页面。
这就是我现在所拥有的:
我有一个主nib文件,其中显示主列表,以及页面共有的所有字段。每种页面类型都有一个带有特定字段的笔尖。主nib文件中有主要的NSArrayController,它填充了NSTableView。每个页面特定的nib中都有一个NSArrayController,这样我就可以将详细信息字段绑定到当前选择的属性。我的所有NSArrayControllers都配置相同,我将它们全部绑定到相同的managedObjectContext和相同的selectionIndexes。
我正在使用Aaron Hillegass的方法进行视图交换,他在他的可可书中描述了这种方法。所以我注册了NSTableViewSelectionDidChangeNotifications,当我收到一个时,它调用方法switchView:
switchView查看当前选定的对象,检查它的页面类型,并根据Hillegass的方法交换相应的nib文件。
如果我只添加一种类型的页面,一切正常,但只要我添加第二种类型的页面,我就会收到此错误:
关键路径选择的错误设置值对象的索引(来自绑定对象实体:页面,所选对象的数量:1):[valueForUndefinedKey:]:实体NoColPage不是键值编码兼容键。
错误的最后一部分是有道理的:它试图显示错误的笔尖,所以它试图绑定到该对象不存在的字段。
我向MyDocument添加了一个selectionIndexes字段,以便我的所有NSArrayControllers都可以绑定到同一个地方。我已经痛苦了好几天了,我无法弄明白。有什么想法吗?
如果有帮助,请此处是您可以下载的示例项目。我从项目中只将与此问题相关的内容提取到一个新的虚拟应用程序中,我一直在测试和使用它。
PS:Interface Builder用于从Core Data实体生成主 - 详细信息接口的工具不能像我想要的那样用于抽象实体。它只为superentitity中的属性创建字段。
编辑:我认为约书亚正在采取行动,但不幸的是,它不起作用 - 我一直遇到同样的问题。起初我很难过,因为我不明白-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
在花费太多时间试图让每个NIB的阵列控制器同步之后,我已经放弃了这种方法。对我来说唯一有用的是以编程方式控制主要笔尖中显示哪些GUI元素及其绑定。这意味着消除其他笔尖。如果您使用的不仅仅是几个文本字段,那么这不是一个真正可持续的解决方案,但它现在适用于我。
在切换视图之前,我仍然遵循约书亚关于取消绑定的建议,但是现在我只将文本字段绑定到arrayController.selection.whateverKey
其他提示
问题是你要将你的笔尖的数组控制器绑定到文档的选择上,这会导致他们尝试(当选择改变时)来表示所选项目。
试试这个:
- 删除笔尖中的绑定。
- 在添加新视图之前,请在代码中连接其绑定。
- 在删除旧视图之前,请在代码中断开其绑定。 醇>
这应该让一切都快乐。