iOS - 何时创建子ViewController而不是UIView子类?

13
也许这是一个傻瓜问题,但我在iOS开发中遇到过很多次。有时候我会开发一个视图组件,希望在多个屏幕上使用,所以我决定继承UIView,并将其变成可以在多个地方使用的东西。
然后,我开始为它添加功能。也许它需要响应NSNotification,或者它应该响应用户的触摸。
在某个特定的点上,我开始思考是否真的应该创建一个UIViewController子类,并将其作为子视图控制器添加到我的UI中。
对于何时将一些行为添加到UIView中,以及何时创建完整的UIViewController,是否存在共识,这一点我们还无法确定。
3个回答

6

我不能告诉你关于共识的事情,但这是我的看法:

只有在以下情况下才需要子类化UIView

  • 您想进行自定义绘制
  • 您需要自定义某些已经存在的UIView子类的行为
  • 您对布局子视图有特殊需求。大多数布局可以由UIViewController完成。
  • 也许需要特殊的触摸处理,无法使用手势识别器完成

在所有其他情况下都要子类化UIViewController。您几乎总是需要一个控制器来编写将视图和模型连接起来的粘合代码,或者处理用户交互。因此,苹果在UIKit中使控制器可以完成所有工作并尽可能保持视图“愚蠢”。例如,非常简单地嵌套控制器以创建复杂的视图层次结构,而无需具有单个视图子类。

指示子类化UIView不是首选操作的指标是“替代子类化”部分,在UIView类参考中。指示子类化UIViewController是首选操作的指标是,在UIViewController类参考中没有这样的部分 :-)


@herzbube,你认为这就是我们现在在IB中使用包含VC子项的容器视图的原因吗?这是共享UI场景中的部分内容(例如个人资料图片+姓名+状态圆点)的正确方式吗? - allaire
@allaire 评论并不是用于讨论的,也不打算这样。你可以在聊天频道中开始这个讨论以获得意见。话虽如此,我承认1)我从未经常使用IB;2)我已经与iOS开发脱节了几个月,所以我不知道IB现在为开发人员提供了什么,以及苹果公司认为应该如何使用它。也许看一两个技术视频? - herzbube

5
每当您需要处理或控制数据时,应使用控制器。视图应尽可能愚蠢,不知道它们正在显示什么,而是知道在哪里显示。您可以轻松地创建子类并重用ViewControllers。例如,假设您需要通过弹出控制器和模态方式在整个应用程序中检索用户的字符串(或文本)。创建一个具有文本字段和按钮视图的通用UIViewController子类。然后,您可以在任何需要的情况下使用此视图及其控制器。将其重用于弹出窗口、模态或任何其他位置,并通过委托通常传递数据。由于您正在处理数据,因此不应仅使用UIView的子类。
根据我的经验,我更经常地创建UIViewControllers的子类,而不是创建UIViews的子类。对于您是否仅谈论容器或在一般应用程序工作流程中重复使用视图,我有点难以理解。无论如何,这都应该是相同的。

美丽。这也一直是我的倾向。 - Matt H.
促使我发布这篇文章的案例实际上是针对一些不会被重复使用的东西...它非常特定于一个特定的屏幕。然而,该组件有很多管道,它真的感觉需要更好地与包含它的ViewController分离开来。 - Matt H.
是的,我知道你的意思。为特定情况子类化UIViewController并不是一个坏主意,但尽量使它们尽可能通用。就像在我的例子中一样,不要将其命名为“ColorNameCollector”之类的名称,因为那样它只能用于获取颜色。相反,将其命名为“StringCollector”之类的名称更加通用,可以在需要从用户处获取字符串时使用,无论它在何处或如何呈现/使用。 - Firo

0

我有时使用嵌入式视图控制器来加载可重用的表视图。我发现它有时很有用,但并非总是如此。两者之间的通信可能很麻烦,例如如果您希望嵌入式控制器向容器进行回传通信。委托使其更加容易,但仍然很麻烦。它还限制了您只能在iOS 6上使用,如果我没记错的话,iOS 5及以下版本不支持嵌入式控制器。

如果只是添加方法,您可以使用类别来存储一些额外的方法。我经常在不想子类化的NSManagedObjects上这样做,如果我从数据模型重新生成NSManagedObject,我不会失去类别中的代码。这为我提供了额外的功能,例如计算字段或转换方法,而无需子类化。如果您不需要特定实例的这些方法,请排除对类别的引用。

在我看来,子类化从来都不是坏事。


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