相关文章
UIViewController
UIViewController类提供了:用于iOS应用程序的视图的基础管理。视图控制器管理一组视图,这些视图构成了应用程序用户界面的一部分。它负责加载和处理这些视图,用于管理与这些视图的交互,以及协调响应相关数据。视图控制器还与其他控制器协调努力,帮助管理您的应用程序的整体界面。
概要
开发者很少直接创建UIViewController类的实例。相反,你继承UIViewController,创建实例和使用这些对象的具体行为和UI。
视图控制器的主要职责包括以下内容:
● 更新视图的内容,通常是响应下层数据的更改。
● 响应用户与视图的交互。
● 缩放视图、管理整体界面布局。
UIViewController与它管理的视图紧密绑定,并参与处理事件的响应链。UIViewController也继承自UIResponder对象,其被插入到视图控制器的根视图和视图的父视图之间的响应链(通常属于不同的视图控制器)。如果UIViewController的视图没有处理事件,视图控制器具有处理该事件的选择或传给父视图。
UIViewController很少单独使用。相反,你经常会使用多个UIViewController,每个UIViewController拥有你应用程序用户界面的一部分。例如,一个UIViewController可以显示一个项目表,而另一个UIViewController则显示该表中的选定项。通常,只有一个UIViewController的视图每次是可见的。一个UIViewController可以呈现一个不同的UIViewController来显示一组新的视图,或者它可以作为其他UIViewController的内容和动画视图的容器。
继承要点
每个应用程序都包含至少一个自定义UIViewController。更多的时候,应用程序包含许多自定义UIViewController。自定义UIViewController定义您的应用程序的整体行为,包括应用程序的外观,以及它如何响应用户交互。以下部分简要介绍了自定义子类执行的某些任务。有关使用和实现视图控制器的详细信息:
视图管理
每个UIViewController管理视图层次结构,它的根视图,即这个控制器的view属性。根视图主要作为视图层次结构的其视图的容器。根视图的大小和位置由拥有它的对象决定,是父UIViewController或应用程序窗口的大小。由UIWindow拥有的视图控制器是应用程序的根视图控制器,它的视图大小为填满window的大小。
UIViewController懒加载他的view。第一次访问视图属性加载或创建视图控制器的视图。有几种方法可以指定视图控制器的视图:
● 指定视图控制器的视图在您的应用程序的脚本。Storyboard是首选方式。有一个Storyboard,你指定的视图和它们的连接的视图控制器。你也可以指定你的视图控制器之间的关系和演变,这使得它更容易看到和修改你的应用程序的行为。
从Storyboard中加载一个视图控制器,调用instantiateViewControllerWithIdentifier:适当的UIStoryboard对象的方法。Storyboard创建视图控制器对象创建并返回到你的代码。
● 使用nib文件作为视图控制器的视图。一个nib文件允许您指定一个视图控制器的视图而不让你继续或定义在视图控制器间的关系。nib文件还存储了视图控制器本身只有很少的信息。
使用nib文件初始化视图控制器对象,创建你的视图控制器类以编程方式使用init(初始化nibname:束:)方法。当其意见要求,视图控制器负载从nib文件。
● 使用loadview()方法指定的视图控制器的视图。在该方法中,创建你的视图层次的编程方式和分配,层次结构的根视图的视图控制器的视图属性。
所有这些技术都有相同的最终结果,即创建适当的视图集,并通过视图属性将它们暴露出来。
note:一个视图控制器是他的view和子view唯一拥有者。它负责创建这些视图和释放,在适当的时候比如当视图控制器本身释放。如果你使用一个storyboard或nib文件来存储您的视图对象,每个视图控制器对象自动获取自己的这些意见的副本。但是,如果手动创建视图,则每个视图控制器必须具有自己的唯一视图集。不能在视图控制器之间共享视图。
视图控制器的根视图总是大小以适应其指定的空间。在视图层次中的其他视图,使用界面生成器,指定自动布局约束,即设置每个视图定位和在父视图的边界内的尺寸。在适当的时候,你也可以通过代码创建和添加约束。
处理生命周期通知
当视图的可见性改变时,视图控制器会自动调用自己的方法,以便子类可以做出更改。使用方法viewwillappear(_:)view即将出现在屏幕上,并使用viewwilldisappear(_:)保存更改或其他状态信息。使用其他方法作出适当的改变。
Figure 1:显示视图控制器视图和可能发生的状态转换。不是所有的“will”回调方法都只与“did”回调方法配对。您需要确保,如果在“will”回调方法中开始一个处理,需要在“did”方法中结束处理,
生命周期状态图:
处理view的转屏
作为iOS 8,所有的旋转相关方法已不被推荐使用。相反,旋转视为在视图控制器的视图的大小变化,因此可以使用viewwilltransition(to:with:)方法。当界面方向的变化,UIKit调用窗口的根视图控制器的这个方法。然后通知其子视图控制器,在视图控制器层次中传递此消息。
在iOS 6和iOS 7,你的应用程序界面方向,在Info.plist文件中设定。视图控制器可以重写supportedInterFaceOrientations方法列出支持方。通常情况下,系统调用这个方法只在窗口或一个视图控制器出现(铺满屏幕)的时候;子视图控制器使用父视图控制器提供的窗口,不再直接参与决定支持什么旋转。该应用程序的orientation mask和视图控制器的 orientation mask的交集是用来确定,一个视图控制器可旋转到方向。
你可以重写视图控制器的preferredInterFaceOrientationForPresentation方法,当全屏出现的时候,指定一个特定方向。
当旋转发生时,可见的视图控制器的方法,willRotate(to:duration:),willAnimateRotation(to:duration:),and didrotate(from)方法被调用。viewWillLayoutSubviews()方法也被调用。如果视图控制器是不可见的,当发生方向改变时,旋转方法不被调用。但是,viewWillLayoutSubviews()被调用,当视图变得可见时。你可以调用statusBarOrientation方法来判断设备的orientation。
note:在启动时间,应用程序应该始终建立他们的界面在纵向方向。经过application(_:didfinishlaunchingwithoptions:)方法返回时,该应用程序使用视图控制器指定的旋转方向,将视图显示到window上。
实现一个view Controller
一个自定义的UIViewController类也可以作为一个视图控制器的容器。view Controller容器管理它所拥有的其他视图控制器的内容,也称为子视图控制器。子控制器的view和其他子控制器的view协同工作。
view Controller容器应该声明一个公共接口来关联它的子类。这些方法的性质取决于您并且取决于您正在创建的容器的语义。你需要决定多少子控制器可以展示你的视图控制器时,当那些孩子们展示,并在他们出现在你的视图控制器的视图层次。您的视图控制器类定义了子控制器们哪些关系(如果有的话)。通过为容器建立一个干净的公共接口,您可以确保孩子在逻辑上使用它的功能,而不会访问太多关于容器如何实现行为的私有细节。
你的容器视图控制器必须关联的子视图控制器本身在加入孩子的根视图的视图层次结构。这允许iOS正确传递事件的子视图控制器和视图控制器管理。同样,在消除子视图的根视图的视图层次,应该断开,从本身的子视图控制器。要创建或取消这些关联,容器调用由基类定义的特定方法。这些方法不能被你的容器类的客户;他们只能由你的容器的实施提供预期的控制行为
以下是您可能需要调用的基本方法:
● addChildViewController(_:)
● removeFromParentViewController()
● willMove(toParentViewController:)
● didMove(toParentViewController:)
note:在创建容器视图控制器时不需要重写任何方法。默认情况下,旋转和出现回调会自动转到子控制器。你可以选择重写shouldAutomaticallyForwardRotationMethods()和shouldAutomaticallyForwardAppearanceMethods方法自己控制这种行为。
内存管理
内存是在iOS中的一个关键的资源,和视图控制器提供在关键时刻减少内存占用的内置支持。通过UIViewController类的方法didReceiveMemoryWarning() ,提供了低内存条件的自动处理,从而释放不必要的内存。
状态保存与恢复
如果你的视图控制器的的restorationIdentifier属性指定一个值,系统可以让视图控制器encode ifself,当app回到后台。当保留时,视图控制器保留视图层次结构中的任何视图的状态,并且还具有恢复标识符。视图控制器不会自动保存其他状态。如果您正在实现自定义容器视图控制器,则必须自己编码所有子视图控制器。您编码的每个子控制器必须具有唯一的恢复标识符。