Iphone UIViewController旋转方法

Iphone UIViewController旋转方法,iphone,ios,cocoa-touch,uiviewcontroller,Iphone,Ios,Cocoa Touch,Uiviewcontroller,哪个对象负责分派UIViewControllerrotation方法调用,即: shouldAutorotateToInterfaceOrientation: willRotateToInterfaceOrientation:持续时间: willanimatefirsthalfofrotationInterfaceOrientation:持续时间: willanimateseSecondhalf of Rotation from Interface定向:持续时间: DidRotateFromI

哪个对象负责分派
UIViewController
rotation方法调用,即:

  • shouldAutorotateToInterfaceOrientation:
  • willRotateToInterfaceOrientation:持续时间:
  • willanimatefirsthalfofrotationInterfaceOrientation:持续时间:
  • willanimateseSecondhalf of Rotation from Interface定向:持续时间:
  • DidRotateFromInterface方向:
我想象它是
UIApplication
(但可能是AppDelegate或UIWindow)

下一个问题是,对象如何知道与哪个
UIViewController
对话

它如何知道哪个
UIViewController
的视图是窗口的子视图


是否有可以发送的消息或可以设置(某个对象的)属性来设置应用程序的“活动”
UIViewController

这都是您不必担心的魔法。只需将控制器的根视图添加到窗口中,或者让选项卡栏或导航控制器为您执行此操作,它就会收到这些消息

(但如果您仔细研究一下调试器,您可能会得出与我相同的结论:存在某种内部表,将每个控制器的视图映射回控制器,并根据该链接发送消息。)


更新:这是我在2009年第一次写下这个答案时真正的私人魔术,但随后对iOS的更改使其背后的API公开了。现在可以通过
UIWindow.rootViewController
属性访问根视图控制器,并使用
UIViewController.childViewControllers
属性形成子视图控制器树


父视图控制器负责通知其子视图的方向更改。(我不确定如何通知根视图控制器,但您可以设置一个断点并自行确定。)
-shouldAutomaticallyForwardRotationMethods
方法决定UIViewController是否为您执行此操作。如果它返回
,您将负责在
-willRotateToInterfaceOrientation:duration:
-willAnimateRotationInterfaceOrientation:duration:
中执行此操作,和
-didRotateFromInterfaceOrientation:
方法。

似乎
UIApplication
正在向活动视图控制器发送消息

但是您的视图控制器实例如何获取这些消息呢

消息被转发到第一个视图控制器,该视图控制器的视图已添加到
ui窗口
实例中

这归结为3种基本场景:

  • 视图为空的ViewController 直接添加到
    ui窗口
    实例(单视图应用程序)

  • 导航控制器位于 基于导航的应用程序,然后 导航控制器转发 将消息发送到活动视图 控制器

  • 选项卡栏中的选项卡栏控制器 基于应用程序,然后是选项卡栏 控制器将消息转发给 活动视图视图控制器(或 主动导航控制器)

  • 您将遇到的问题是,如果您构建一个具有多个视图的应用程序,但不使用导航控制器或选项卡栏控制器。如果手动在
    ui窗口
    实例内外交换视图,则无法可靠地接收这些消息。 这类似于这样的帖子:

    只需使用苹果的多视图约定,就可以了。希望这能节省一两个小时

    它如何知道哪个UIViewController的视图是窗口的子视图

    UIViewController类维护视图及其视图控制器之间的静态映射。该地图在CocoaTouch内的几个关键位置进行查询。特别是,[UIView nextResponder]查询它并返回控制器(如果找到)


    我猜UIWindow会对其根视图执行相同的查找,以了解将旋转事件转发到哪个控制器。下次我会检查这个,我会在拆卸中查找一些东西。(我花了一些时间对CocoaTouch进行反向工程,以了解那里的情况。)

    我也有类似的问题

    我有一个横向的游戏(左右横向)

    为了管理多视图应用程序,我使用根UIviewController,即带有UIview的虚拟UIviewController,该UIview不执行任何操作。然后,我将每隔一个UIview作为子视图添加到其中

    启动应用程序时,仿真器会快速旋转到纵向,我得到的每个视图的框架属性都类似于(0,-80320480)。这将导致视图被右侧的160 X 320矩形剪裁

    我注意到每个子视图的–shouldAutorotateToInterfaceOrientation:方法只调用一次,当它添加到根视图时就会发生这种情况。稍后,旋转设备时,只有根视图才能调用其方法

    毫不奇怪,–willAnimate*方法调用中的任何一个都只发送到根视图,因此,在子视图中定义这些方法都是毫无意义的

    每次将方向更改为–shouldAutorotateToInterfaceOrientation:方法接受的方向时,都会调用这些方法。所以我想我可以从那里改变我的子视图的框架属性

    为了实现这一点,我在rootViewController类中定义了以下方法:

    - (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation duration:(NSTimeInterval)duration
    {
        subview1_ViewController.view.frame = CGRectMake(0,0,480,320);
        subview2_ViewController.view.frame = CGRectMake(0,0,480,320);
            ...
    }
    
    我不明白为什么框架属性没有更新,但我知道这个解决方法是可行的


    希望这能有所帮助……

    好问题,我从几天起就有这种怀疑。我正要问类似的问题,突然遇到了这个问题!我应该像你一样问我的问题。这些都是与通用框架相关的问题,“定制框架,阅读文档,好吧,现在我该怎么知道?”