你可以将NIB文件换成已经在屏幕上的UIViewController吗?

时间:2010-01-06 22:48:27

标签: iphone uiviewcontroller nib

例如:

  1. 使用“nib-v1”
  2. 使用initWithNibName创建新的UIVC
  3. 显示它,例如使用[(UINavigationController)nav pushViewController:myVC]
  4. 将myVC正在使用的NIB更改为“nib-v2”
  5. 据我所知,这是许多应用程序的“正确”应用程序设计方法,在分析信息时,您需要两个略有不同的UI屏幕才能显示信息。

    例如,您的大部分页面都是文本,但其中一些页面也有图像(想想RSS阅读器,其中一些RSS条目有文本+图像,有些只是文本)。

    我之前通过使用一个NIB文件和第二个不可见的名为UIView的实例处理了这个问题,我在第一个实例的顶部分层,并根据上下文打开/关闭,使用“隐藏”标志。

    但这显然是错误的,浪费了记忆。

    但是,我看不到从NIB文件“重新加载”视图的明显方法。我猜我想以某种方式重现initWithNibName所做的魔术?

    我怀疑这是可能的,但我敢肯定,如果你以“错误的方式”这样做,那么应用程序就会崩溃。

5 个答案:

答案 0 :(得分:7)

您可以随时执行

[[NSBundle mainBundle] loadNibNamed:@"FileName" owner:viewController options:nil]];

但如果您不确定自己在做什么,这无疑会非常糟糕,尤其是如果这两个笔尖都连接了view

您应该重新设计视图控制器层次结构,以便在从两个不同的nib文件加载的两个不同控制器之间进行交换。


或者,您可以让控制器管理从与nibName无关的不同文件加载的交换视图。在这种情况下,您可以按上述方式加载它们。并且您希望将他们的插座(例如,subviewOnesubviewTwo)连接在不同的笔尖中。

答案 1 :(得分:4)

您应该检查UINib类,看它是否符合您的要求。它将允许您加载一个nib文件并将其保存在内存中。

但只是为了澄清:您是否要修改nib文件本身?或者你想在加载到内存中时修改nib文件的内容吗?

在我的头顶,第一个将是非常困难的(你不能修改原始文件,因为它是应用程序包的一部分...也许你将它复制到Documents文件夹并编写自己的编码器/解码器?)第二个更容易,但我不确定原因是什么?为什么不在加载后修改viewController / view(例如,在awakeFromNib中),如果你希望这些更改保持不变,那么将这些更改保存到文件中。

简而言之,我并不确切地知道你想做什么,但我觉得可能有更好的方法可以做到这一点。

答案 2 :(得分:2)

我同意Rob,但是如果你真的想要交换笔尖(这很糟糕,因为它很容易导致悬挂指针之类的东西),你可以使用{{1}从新笔尖加载视图} NSBundle方法,并自己交换视图。

您应该为不同类型的内容使用不同的视图控制器。如果它们只是略有不同,您仍然可以考虑创建一个基类并为不同的变体创建子类。

答案 3 :(得分:0)

您不应该更改UIViewController使用的NIB文件。将NIB附加到UIViewController应该是一次性事件。隐藏的意见很好;他们当然不是明显错误的。您还可以在加载后以编程方式添加视图元素。如果你正在做很多事情,你可以完全跳过NIB并以编程方式在-loadView中构建视图。其中任何一个都没问题,但初始化后不要切换NIB。我甚至不建议您为给定的UIViewController类选择多个NIB;这太令人困惑了。通常,每个NIB应映射到具有非常相似(或相同)名称的专用UIViewController类。

在相关说明中,我建议将NIB的名称移动到UIViewController中,如earlier posting中所述。

答案 4 :(得分:0)

我来找同样问题的答案,最后解决了这个问题:

UIViewController* ctrler = [[UIViewController alloc] initWithNibName:@"NewControllerNIB" bundle:nil];

// Replace previous controller with the new one
UINavigationController* nav = self.navigationController;
[nav popViewControllerAnimated:NO];
[nav pushViewController:ctrler animated:NO];

我不确定当前控制器是否可能在执行推送新控制器的调用之前被解除分配,但到目前为止它似乎有效(直到我用更好的方法重新设计应用程序)