UIViewController是否总是应该作为视图控制器层次结构的一部分?

3
在下面的应用程序中,我目前使用了三个UIViewControllers:一个主视图控制器,一个用于主菜单,一个用于由主菜单启动的设置屏幕。随着我对UIViewController的工作原理和设计目的的了解越来越多,我开始质疑我的架构是否明智。
在我看来,子类化的主要目的是能够重写在控制器的生命周期中自动调用的方法:viewDidAppear,viewWillAppear,willRotateToInterfaceOrientation等。似乎只有当UIViewController(或其子类)是UIViewController层次结构的一部分时,才会调用这些方法。因此,除非我将使用标准的创建视图控制器层次结构的方法之一,否则没有必要子类化UIViewController,例如UINavigationController,[UIViewController presentModalViewController]等。
我不愿意使用Cocoa风格的添加视图控制器到层次结构的方法,因为它们都似乎非常受限制。例如,我可以使用[UIViewController presentModalViewController]显示我的设置屏幕,但我不想它遮挡整个屏幕。有背景动画,我希望用户能够在设置屏幕可见时与之交互。
以下是我的问题:
1)除非我将其通过Apple的技术之一添加到viewController层次结构中,否则子类化UIViewController是否愚蠢?
2)我的假设是否正确,即内置的显示新视图的方法对我来说太受限制了,为了获得所需的灵活性,我需要通过[view addSubview]加载视图?
3)如果子类化UIViewController对于我的菜单和设置视图没有意义,那么我应该如何避免将所有代码放在一个庞大的UIViewController子类中?我只是应该子类化NSObject,添加适当的IBOutlets和IBActions,并在使用[NSBundle loadNibNamed]加载nib时将其作为文件所有者传递吗?
图片如下:https://istack.dev59.com/DBNFN.webp
1个回答

5

很好的问题。首先,需要澄清一下:你所说的“苹果技巧之一”在UIViewController编程指南中被称为“间接呈现”,包括模态呈现、被推入导航栏堆栈、呈现一个弹出视图控制器等。基本上,所有这些视图控制器方法都被视为“间接”呈现方法,而使用-addSubview:(例如[someView addSubview:myViewController.view])被视为“直接”呈现。

来自编程指南的引用:

建议您仅使用建议的技术来显示视图控制器的视图。为了正确地呈现和管理视图,系统会记录您直接或间接显示的每个视图(及其关联的视图控制器)。稍后,它将使用此信息向您的应用程序报告与视图控制器相关的事件。例如,当设备方向改变时,窗口使用此信息来识别最前面的视图控制器并通知其进行更改。如果您通过其他方式将视图控制器的视图合并到层次结构中(例如将其添加为某些其他视图的子视图),则系统会假定您想自己管理该视图,并且不会向关联的视图控制器对象发送消息。除了设置应用程序的初始界面外,大多数其他视图都是通过它们的视图控制器对象间接呈现的。这就是说,如果您只是直接将视图添加到视图层次结构中并没有采取其他进一步的操作(键窗口是例外),那么您正确地认为所有这些UIViewController消息都将被浪费。该引用还提到,最常见的是使用间接呈现。

1) 我不确定是否可以笼统地说“除非您间接呈现它,否则在所有情况下都将UIViewController子类化是愚蠢的。”我相信在某些情况下有一些好的用途。我只能说我个人从未这样做过。

2) 当然,在这里我不会使用UIViewController子类。

3) 请允许我引导您关注编程指南的另一个领域:

在iPhone应用程序中,视图层次结构中的视图通常覆盖整个屏幕...如果您想将视图层次结构分为多个子区域并单独管理每个子区域,请使用泛型控制器对象(从NSObject下降的自定义对象)而不是视图 控制器对象来管理每个子区域。然后使用单个视图控制器对象来管理通用控制器对象。

这很清楚地与您想要在这里做的事情同步。您对自己建议的方法非常正确。那个“由主菜单启动的设置屏幕”应该由从NSObject下降的通用控制器对象来管理,然后由全屏UIViewController子类来管理。


总是很高兴听到“你说得很准确” :) 非常感谢您提供非常有帮助的答案。 - morgancodes

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接