在iPhone上何时使用UIView和UIViewController?

57

我一直在疑惑在iPhone上何时使用UIView和UIViewController。

我知道除非是全屏视图,否则不应该使用UIViewController,但还有哪些指导方针呢?

例如,我想构建一个模态覆盖层 - 一个会滑动到当前屏幕上的屏幕。 如果这个模态覆盖层是全屏的,是否应该使用UIViewController呢?上次我构建类似的东西时,我子类化了UIViewController,但现在我想知道那是否正确。

9个回答

39

来自苹果的iOS视图控制器编程指南

"视图控制器最重要的作用是管理视图层次结构。每个视图控制器都有一个单一的根视图,它包含了所有视图控制器的内容。在该根视图中,您可以添加需要显示内容的视图。"

此外:

"有两种类型的视图控制器:

  • 内容视图控制器管理应用程序的离散内容,并且是您创建的主要视图控制器类型。
  • 容器视图控制器从其他视图控制器(称为子视图控制器)收集信息,并以便于导航或以不同的方式呈现这些视图控制器的内容的方式呈现它们。

大多数应用程序都是两种类型的视图控制器的混合体。


1
这个答案需要进行修改,因为它已经非常过时并且误导了很多人,包括我自己。这个答案几乎让我改变了我的应用程序中的很多东西,直到我发现如果你在iOS5或更高版本中工作,其中没有一个适用。VC(视图控制器)不再被认为是"带有UIView的屏幕"。VC现在可以包含其他VC在容器视图中,并被称为子VC或容器VC。将子VC添加到父VC中不会破坏旋转功能。它仍将从父VC的角度进行旋转。 - datWooWoo

11

这是一个很好的问题。

我的基本经验法则是,每个应用程序的主要“页面”都会有自己的视图控制器。这意味着在应用程序设计的线框阶段,一切作为独立实体存在的内容最终将由其自己的 View Controller 管理。 如果有一个模态屏幕滑过现有屏幕,我会考虑将其视为单独的“页面”,并为其分配自己的视图控制器。如果有一个覆盖现有页面的视图(例如加载屏幕或帮助弹出窗口),我会对它们进行不同的处理,将它们实现为 UIView 子类,并将逻辑保留在该“页面”的视图控制器中。如果弹出窗口具有行为,则将使用委托模式向那些页面的 View Controller 进行通信。

希望这有所帮助。这是非常哲学和架构问题,还有很多可以写的内容。


4

每当一个视图是全屏的,并且具有出口/操作和/或子视图时,我使用UIViewController。


3
将所有屏幕元素放在一个UIViewController中,直到该视图控制器的代码过多,然后将屏幕拆分为多个UIViewControllers,并由一个主视图控制器包含...
为了将您的答案置于上下文中,为该模态叠加层创建一个视图控制器。如果您正在使用导航控制器来呈现它(而您可能应该这样做),那么它将具有一个视图控制器。

因为这个回答被不合理地踩到了-5,所以我点了个赞。Kendall的建议是一种选择,符合重构的精神,而不是试图预见所有事情。 - Kartick Vaddadi
谢谢,我认为人们可能误读了我的回复,所以我更新了它以便更清晰。或者也许人们只是喜欢预先优化... - Kendall Helmstetter Gelner
虽然这个答案并不是很惊艳,而且可能有点间接,但我认为它被过分处罚了,所以我给了一个+1。如果你真的不知道何时开始拆分你的VC,这似乎是一个相当不错的起点。 - bitwit
1
因为和其他人一样的原因点赞,0现在看起来好多了。 - user2782993

2

我有一种稍微不同的方法:

如果您计划在drawRect中进行自定义绘制,请覆盖UIView。否则,子类化UIViewController并使用[self.view addSubview:blah]添加页面组件。

还有一些其他特殊情况,但这处理了大约95%的情况。

(您仍然经常需要具有自定义UIView的UIViewController。但通常会有一个没有相应自定义UIView的自定义UIViewController。)


0
这个东西是在一个自包含的屏幕中滑动吗?我的意思是,它是否直接与父视图交互?如果是,将其设置为UIView,否则,建议使用UIViewController

在这种情况下,叠加层是 Lite 应用程序的一部分。当用户尝试进行受限活动时,模态叠加层会弹出并警告他们。它将在多个视图控制器中使用,但它会根据用户尝试执行的操作显示不同的消息。该叠加层基本上具有一个消息和一个小型 UIWebView,用于展示可点击广告,将其带到应用商店的完整版本上。 - Andrew Johnson
有趣。我认为这可以两种方式实现,但我可能会将其制作为UIView。我认为UIView更容易在其他UIViewControllers上重用。但这当然是个人观点。 - marcc
我在我的应用程序中做了这件事:用户达到第三级,我弹出一个视图,上面写着“您已经达到最后一关,请点击此处前往应用商店购买完整版。”但是这个功能被苹果拒绝了。 - mahboudz
啊。但是现在允许在免费应用程序中进行应用内购买,将该视图更改为“点击此处购买其余关卡”,您就得到了一个解决方案。 - marcc

0

UIView是UIViewController的一部分,请参阅UIViewController的view属性。正如你正确指出的,UIViewController管理一个完整的屏幕,一次只能有一个可见的UIViewController。但在大多数情况下,您会在屏幕上看到更多的UIView或其子类。

你给出的例子在大多数情况下是正确的使用方式。正如你可能已经注意到的,当子类化UIViewController时,您将获得很多功能。其中之一就是对UIViewController的出现和消失进行动画处理。

正如marcc指出的,如果您要滑入的东西不是一个独立的屏幕,最好使用UIView。

总结一下,如果您想要使用子类化UIViewController带来的功能,那就选择它,将其设置为UIViewController。否则,UIView可能更合适。

iTunes U Standford课程有一堂关于UIViewControllers的精彩讲座,我推荐观看,因为它包含了关于UIViewControllers的许多信息。


0
如果您熟悉MVC模式,那么您应该能够理解UIVIew和UIViewController之间的区别。简单来说,UIView用于在屏幕上呈现UI元素。UIView是几乎所有Cocoa Touch UI元素的超类。这些元素不知道它们应该显示什么信息,当用户点击按钮时应该做什么,异步网络请求完成后会发生什么等等。UIViewController则负责处理这一切及更多内容。视图控制器负责将UI元素放置在屏幕上的正确位置,设置UI元素的内容,处理按钮按下和其他用户输入,根据需要更新模型等。
从概念上讲,单个UIViewController控制iPhone应用程序中整个屏幕的内容,这就是为什么通常很容易以视图控制器的方式考虑事物。如果您需要一个视图,用户可以在其中选择食谱的配料,那么您将需要一个UIViewController。我为自己做出了这种区分,因为我来自Java背景,我不习惯框架强制实施MVC。我会考虑UIView,并以此方式开始实现它们,然后因此遇到各种问题。如果您要坚持使用UIKit进行应用程序开发,则Apple为您提供的工作流程是:为应用程序中的每个单独视图创建一个UIViewController子类,然后使用Interface Builder放置UI元素并创建按钮等连接。它非常有效,节省了大量时间,并使您集中精力使您的应用程序功能良好。

0
  1. 我使用UIViewController来显示全屏视图。

  2. 为了更好地控制自定义视图,我更喜欢使用UIViewController的子类而不是UIView,之前我使用UIView来创建自定义子类。


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