5

我正在打开一个新问题来跟进我的最后一个问题(添加子视图后 superview 和 parentviewcontroller nil)。基本上我知道使用子视图是一个好主意,但是我不应该有一个 ViewController 来控制一个存在于另一个 ViewController 中的子视图。基本上我想做以下事情......我有两个 ViewControllers 共享一个公共子视图。我已经将该子视图创建为一个名为 SearchDate.xib 的 nib。文件所有者是相应的类 SearchDateView.m/h。该类在笔尖中的 UIView 内有一个唯一元素的出口,它是一个标签。SearchDateView 类还具有更改 SearchDateView.xib 中标签值的功能。我希望我的两个 ViewController 都加载这个笔尖,但显然我不知道如何正确加载笔尖。无论我做什么,充其量都没有显示,最坏的情况是抛出异常。苹果文档谈到将 IB 中的其他类实例直接拖入您的主视图,但这似乎没有奏效。我的 ViewController 中有一个 SearchDateView 插座,我尝试在控制器的加载视图上执行此操作:

searchDateView = [[[NSBundle mainBundle] loadNibNamed:@"SearchDateView" owner:self options:nil] objectAtIndex:0];
[[self view] addSubview:searchDateView];

但我得到了这个例外:

*** Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[<MainViewController 0x431fac0> setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key searchDateLabel.'

我知道我在做一些完全错误的事情,但是拥有一个 nib、关联视图类来更新该 nib 中的一些对象并在不同的控制器中重用该 nib 的正确方法是什么?

编辑:鉴于评论可能还不够清楚。我不想对整个视图使用相同的 nib 文件 - 而不是子视图。因此,例如控制器 A 有一个地图和一个 SearchDateView,控制器 B 有一个表视图和一个 SearchDateView。所以我想知道如何将子视图加载到多个控制器中......

4

2 回答 2

2

当使用 initWithNibName:bundle: 初始化每个控制器时,为多个控制器使用相同的 NIB 文件应该没有问题。不过,您通常不会从控制器内加载控制器自己的 nib 文件。

如果您使用 loadNibNamed::: 加载 nib 文件,那么您将获得一个 NSArray ,其中定义了对象,因此您不能直接将其用作视图。获得视图的一种方法是使用 for() 或其他方法搜索数组以找到您想要的对象,但如果您设置 owner:self 那么它应该连接到连接到 self 中的 File's Owner 的插座,因为 File's Owner 将是 self . 但是在这种情况下你可以丢弃返回值;您不需要返回的数组。如果您连接了该插座,那可能是您的主要问题(用阵列破坏插座)。

可以使用 loadNibNamed 来加载特定的视图对象(假设您从返回的数组中选择它),然后以某种方式显示它,但在控制器上使用 initWithNibName 通常更容易(在这种情况下,文件的所有者将是控制器) .

哦,您还可以在 Interface Builder 中为控制器设置 nib 文件。对多个控制器使用相同的 nib 应该没有问题,因为基本上你只是告诉 Interface Builder 设置 nib 文件来执行类似 initWithNibNamed 的操作。单击控制器对象并检查检查器窗口。

更新

我可能会这样做是为了在多个控制器中只使用一个视图:

    NSArray *nib = [[NSBundle mainBundle] loadNibNamed:@"FooView" 
                                                 owner:self options:nil];
    for (id obj in nib)
        if ([obj isKindOfClass:[FooView class]])
            myNewView = (FooView *)obj;

(从“开始 iPhone 3 开发”的示例代码中的第 8 章:单元格 2 中窃取。)

您可以使用 IB 中的 outlet 执行此操作,在这种情况下,您可以省略 for 循环,但您可能需要一个超类来声明 outlet 的两个控制器,并告诉 Interface Builder File's Owner 是该超类的一个实例所以它知道插座。可能不值得麻烦。

于 2010-01-14T18:43:58.897 回答
0

我的 ViewController 中有一个 SearchDateView 插座,我尝试在控制器的加载视图上执行此操作:

searchDateView = [[[NSBundle mainBundle] loadNibNamed:@"SearchDateView" owner:self options:nil] objectAtIndex:0];
[[self view] addSubview:searchDateView];

但我得到了这个例外:

 *** Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[<MainViewController 0x431fac0> setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key searchDateLabel.'

在没有 Cocoa Bindings(仅在 Cocoa 中可用,而不是 Cocoa Touch)的情况下,我不认为这两者是相关的。

在 Xcode 中,在 上添加一个符号断点objc_exception_throw,然后在调试器中运行您的应用程序。当它中断时,查看调用堆栈。您将能够找到问题的真正根源。

于 2010-01-16T08:19:44.980 回答