您可以将 NIB 文件替换为屏幕上已经存在的 UIViewController 吗?

发布于 2024-12-04 18:53:29 字数 566 浏览 1 评论 0原文

例如:

  1. 使用 initWithNibName 创建一个新的 UIVC,使用“nib-v1”
  2. 显示它,例如使用 [(UINavigationController) nav PushViewController: myVC]
  3. 将 myVC 使用的 NIB 更改为“nib-v2”

据我所知,对于许多应用程序来说,这是“正确”的应用程序设计方法,在分页信息时,您需要两个略有不同的 UI 屏幕来显示信息。

例如,大多数页面都是文本,但其中一些也有图像(想象一下 RSS 阅读器,其中一些 RSS 条目具有文本 + 图像,有些只有文本)。

我之前已经处理过这个问题,方法是让一个 NIB 文件带有第二个不可见的命名 UIView 实例,该实例位于第一个实例的顶部,并使用“隐藏”标志根据上下文打开/关闭。

但这显然是错误的,并且浪费内存。

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

我怀疑这是可能的,但我确信如果您“以错误的方式”执行此操作,那么该应用程序将会严重崩溃。

For instance:

  1. Create a new UIVC using initWithNibName, using "nib-v1"
  2. Display it, e.g. using [(UINavigationController) nav pushViewController: myVC]
  3. Change the NIB that myVC is using to "nib-v2"

So far as I can see, this is the "correct" approach to app-design for a lot of apps, when paging through information where you need two slightly different UI screens for the info being displayed.

For instance, most of your pages are text, but some of them have an image too (think of an RSS reader, where some RSS entries have text + image, some are text only).

I've dealt with this previously by having one NIB file with a second, invisible, named UIView instance that I layered over the top of the first one, and switched on/off depending on on context, using the "hidden" flag.

But this is clearly wrong, and wastes memory.

However, I cannot see an obvious way to "reload" the view from the NIB file. I'm guessing I want to somehow reproduce the magic that initWithNibName does?

I suspect this is possible, but I'm sure that if you do it "the wrong way" then the app will simply crash horribly.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

很快妥协 2024-12-11 18:53:29

您始终可以执行,

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

但如果您不确定自己在做什么,这无疑会真正把事情搞砸,特别是如果 view 在这两个笔尖中都已

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


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

You can always perform

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

but this will undoubtedly really mess things up, if you're not sure what you're doing, especially if view is connected in both of those nibs

You should redesign your view controller hierarchy to swap between two different controllers that load from two different nib files.


Alternately, you can have the controller manage swapping views that it loads from different files that are unrelated to it's nibName. In that case, you can load them in the above manner. And you will want to have their outlets (to, for example, subviewOne and subviewTwo) connected in different nibs.

自演自醉 2024-12-11 18:53:29

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

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

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

简而言之,我不知道你到底想做什么,但对我来说,很有可能有更好的方法来做到这一点。

You should check out the UINib class to see if it does what you want. It will allow you to load a nib file and keep it in memory.

But just to clarify: Do you want to modify the nib file itself? Or do you want to modify the contents of the nib file when it has been loaded into memory?

Off the top of my head, the first would be quite difficult (you can't modify the original file, since it is part of application bundle...maybe you copy it to Documents folder and write your own coder/decoder?) The second is easier, but I am not sure what the reason would be? Why not just modify the viewController/view after it has been loaded (in awakeFromNib, for example) and, if you want those changes to persist, save those changes to file afterwards.

In short, I don't know exactly what you would like to do, but the chances seem high to me there might be a better way to do it.

与酒说心事 2024-12-11 18:53:29

我同意 Rob 的观点,但如果你真的想搞乱交换笔尖(这很糟糕,因为它很容易导致悬空指针等),你可以使用 NSBundle- (NSArray *)loadNibNamed:(NSString *)name Owner:(id)owner options:(NSDictionary *)options 方法并自行进行视图交换。

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

I agree with Rob, but if you really want to mess with swapping nib's (which is bad as it can easily lead to dangling pointers and the like), you could maybe load the view from the new nib with NSBundle's - (NSArray *)loadNibNamed:(NSString *)name owner:(id)owner options:(NSDictionary *)options method and do the view swapping yourself.

You should rather use different view controllers for different types of content. If they only differ slightly, you can still consider creating one base class and subclassing the different variations.

﹏半生如梦愿梦如真 2024-12-11 18:53:29

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

在相关注释中,我建议将 NIB 的名称移至 UIViewController 中,如 早期发布

You shouldn't change what NIB file a UIViewController uses. Attaching the NIB to the UIViewController should be a one-time event. The hidden views are fine; they're certainly not clearly wrong. You can also programmatically add view elements after loading. If you're doing a lot of that, you can skip the NIB entirely and programmatically build the view in -loadView. Any of these are fine, but don't switch the NIB after initialization. I don't even recommend having multiple NIBs that you choose between for a given UIViewController class; it's just too confusing. Generally each NIB should map to a dedicated UIViewController class with a very similar (or identical) name.

In a related note, I recommend moving the name of the NIB into the UIViewController, as described in an earlier posting.

知足的幸福 2024-12-11 18:53:29

我来寻找同一问题的答案,最终像这样解决了它:

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];

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

I came looking for an answer to the same problem, and ended up solving it like this:

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];

I'm not sure if it's possible the current controller gets deallocated before the call to push the new controller is executed, but so far it seems to work (until I just redesign the app with a better approach)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文