只为此心无垠

A blog for Jekyll

凤凰花开开两季,之余青春止于青春


Download the theme

Why won't my UIViewController rotate with the device?

问:为什么我的UIViewController不能跟随设备旋转?

答:UIViewController类为iOS应用程序提供了基本的视图管理模型。它自动支持旋转控制器的视图,以响应设备方向的改变。如果视图和子视图的autoresizing调整属性被正确配置,那么在大多数情况下,此行为是自动的。下面是一个相当详尽的列表,列出了视图控制器不能旋转的原因。

重要提示: iOS 6引入了对自动旋转的巨大更改。这些更改仅适用于针对iOS 6 SDK进行链接的应用。未在iOS 6 SDK中构建的应用程序将在iOS 6设备上运行时收到旧的自动旋转行为。与最新SDK链接的应用程序应包括对旧自动旋转行为的支持(如果其部署目标小于iOS 6)。有关详细信息,请参阅View Controller Programming Guide

  • 您已经将视图控制器的UIView属性作为子视图,添加到UIWindow

    不建议将任何视图控制器的view属性添加为UIWindow的子视图。在didFinishLaunchingWithOptions :返回之前,应该在Interface Builder中或通过运行时,将应用程序的根视图控制器赋值给app window'srootViewController属性。如果需要同时显示多个视图控制器的内容,您应该自定义容器视图控制器并将其用作根视图控制器。请参阅 Creating Custom Container View Controllers

    注:  请记住,UINavigationControllerUITabBarController能够管理自己的堆栈或视图控制器列表。

    从iOS 6开始,如果根视图控制器尚未赋值给应用程序的窗口,支持的方向仅由确定的UIApplication对象。此外,视图控制器不会被通知的方向变化,这可能会导致异常。

  • 视图控制器不支持新的方向。

    从iOS 6开始,视图控制器可以通过重写此方法限制其支持的方向:

    - (NSUInteger)supportedInterfaceOrientations;

    supportedInterfaceOrientations的默认实现返回一个方向,这个方向代表当前设备的惯用推荐方向。也就是说,UIInterfaceOrientationMaskAll在iPad设备上返回,UIInterfaceOrientationMaskAllButUpsideDown在iPhone设备被返回。除非视图控制器管理的内容只能在这些方向的一个子集来显示,才需要重写此方法。如果覆盖此方法,您的实现必须返回UIInterfaceOrientationMask值的按位组合。

    在iOS 5及以下,视图控制器可以通过重写这个方法支持多种方向:

    - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation;

    即使实现shouldAutorotateToInterfaceOrientation,你应该确保它为所有你想支持的方位返回YES。如果interfaceOrientation等于UIInterfaceOrientationPortrait,默认实现返回YES,锁定视图控制器为竖屏。要支持所有的方向,总是返回YES

  • 应用程序不支持和视图控制器同一方向。

    从iOS 6开始,UIKit会同时使用UIApplication对象和最上面的视图控制器来确定支持的方向。在应用程序Info.plistUISupportedInterfaceOrientations键必须包含您的应用支持每个方向的值。系统使用这些值来获得应用程序的支持方向掩码(按位组合)。应用程序委托可以实现application:supportedInterfaceOrientationsForWindow:,返回UIInterfaceOrientationMask,代替原来应用程序的Info.plist中的值。

    重要提示:  通常,最上面的视图控制器topmost controller就是指窗口的根视图控制器,除非当前呈现了另一个控制器,在这种情况下,所呈现的视图控制器就成为最上面的视图控制器。最上面的视图控制器不应该与导航控制器topViewController混淆。

    在iOS 5及以下,在应用程序的Info.plistUISupportedInterfaceOrientations键的值仅作为一个提示,它告诉Springboard应该应用程序启动之前,重新定位的状态栏。它不会在应用启动后限制其支持的方向。

  • 视图控制器拒绝旋转。

    从iOS 6开始,当UIKit中确定可能需要进行旋转,它调用最顶层的视图控制器的方法shouldAutorotate,来确定是否继续选择。此方法默认返回YES; 然而,视图控制器可以通过重写shouldAutorotate以返回NO,在运行时动态禁用自动旋转。

  • 视图控制器是另一个视图控制器的子级。

    从iOS 6开始,只有最上面topmost的视图控制器(沿着UIApplication对象)参与决定是否响应设备方向的改变而旋转。通常,显示您的内容的视图控制器是常用容器控制器的子级,如UINavigationControllerUITabBarController或自定义容器视图控制器的子级。你可能会发现自己需要子类化容器视图控制器,以便修改其supportedInterfaceOrientationsshouldAutorotate方法的返回值。

    注意:  在修改UIKit类(例如UINavigationController)的旋转行为时,应始终优先考虑子类化(创建UINavigationController + category)。因为其他类可能依赖于UIKit容器视图控制器的现有行为,category引入的更改可能会导致意外的行为。

  • 视图控制器重写initinitWithNibName:bundle:但不调用父类的实现。为了正确初始化的对象,在如何初始化方法中则必须调用super initsuper initWithNibName

  • UITabBarController还是UINavigationController的所有子视图控制器不要在一个共同的方向设定达成一致。

    在iOS 5及以下的,以确保所有的子视图控制器正常旋转,则必须实现代表每个选项卡或导航级的每个视图控制器的shouldAutorotateToInterfaceOrientation。每个都必须同意相同的方向,才会发生的旋转。也就是说,对于相同的方向,它们都应该返回YES

  • 该视图控制器以编程方式改变其子视图的布局。

    某些布局是不可能仅使用autoresizing masks就可以完成实现。视图控制器可以通过改变自己的frameboundscenter属性,来手动布局其子视图。开发人员不应该把布局代码放到旋转方法,如由视图控制器重写的旋转方法shouldAutorotateToInterfaceOrientation。有些情况下,旋转发生了,但是并没有调用这些接口方法,从而使视图控制器的子视图处于不一致的状态。

    如果应用程序只支持的iOS 5或更高版本,你应该把视图控制器的布局代码放置在viewWillLayoutSubviews:viewDidLayoutSubviews:方法,控制器方法。

    如果应用程序必须支持的iOS 4,应该将布局代码放置在layoutSubviews方法,此方法是视图控制器的view的方法。

最近的文章

View Controller Catalog for iOS(五)-Popovers

Popovers虽然本身不是一个视图控制器,UIPopoverController类管理视图控制器的呈现。您可以使用popover controller对象展示当前内容,popover是一个浮动在你的应用程序的窗口上方的可视化图层。Popovers提供呈现或收集来自用户的信息的轻量的方式,并常用在以下情况: 要在屏幕上显示对象的信息 管理经常访问的工具或配置选项 呈现一个动作列表,来执行视图内某个对象 竖屏时,要从split view controller呈现一个窗格对于上述操作,...…

View Controller Catalog for iOS继续阅读
更早的文章

Building an Adaptive Interface

构建自适应界面自适应界面应响应trait和大小的变化。从视图控制器级别,使用trait,粗略确定显示的内容和内容的布局。例如,size class改变时,您可以选择更改视图属性,显示或隐藏视图,或显示完全不同的视图。做出这些重大决定之后,可以使用大小的变化进行微调您的内容。适应trait的变化Traits提供了一种为因环境不同而配置应用程序不同的方法,您可以使用它们对界面进行粗调。使用traits进行的大部分更改可以直接在故事板文件中完成,但有些需要额外的代码。配置故事板,来处理不同尺寸的...…

View Controller Programming Guide for iOS继续阅读