Objective c 第二次调用loadView时,iOS 5未自动旋转视图
当我在横向模式下运行应用程序时,第二次加载视图控制器的视图并调用Objective c 第二次调用loadView时,iOS 5未自动旋转视图,objective-c,ios,uiviewcontroller,ios5,rotation,Objective C,Ios,Uiviewcontroller,Ios5,Rotation,当我在横向模式下运行应用程序时,第二次加载视图控制器的视图并调用loadView时,iOS 5不会将根视图控制器的视图从纵向旋转,也不会调用视图控制器的willRotate/willAnimateRotation/didRotate方法 如前所述,只有在卸载视图并且第二次调用loadView后才会发生这种情况。在我的应用程序中,我有时会先以编程方式卸载视图控制器的视图,然后再将其设置为根视图控制器。但是,当由于内存不足警告而自动卸载视图控制器的视图时,也会发生这种情况 这只发生在iOS 5上,而
loadView
时,iOS 5不会将根视图控制器的视图从纵向旋转,也不会调用视图控制器的willRotate/willAnimateRotation/didRotate方法
如前所述,只有在卸载视图并且第二次调用loadView
后才会发生这种情况。在我的应用程序中,我有时会先以编程方式卸载视图控制器的视图,然后再将其设置为根视图控制器。但是,当由于内存不足警告而自动卸载视图控制器的视图时,也会发生这种情况
这只发生在iOS 5上,而不是iOS 4.x上。它很容易在iOS模拟器中重现,下面是一个指向重现此问题的独立测试应用程序的链接:
要查看问题,只需编译应用程序并使用iOS 5.0模拟器在横向模式下启动它,然后点击“A”和“Back”,您将看到如何不发生旋转
有什么想法吗?这与我设置window.rootViewController的方式有关吗?我通过它进行了调试,似乎在4.3和5.0之间发生了变化。在4.3 UIKit中调用
[UIWindow addRootViewController:
,在5.0中调用[UIWindow setRootViewController:
。所以也许有些东西改变了,我们看不到
我建议通过not使用[newController setupStuff]
(因此not将视图设置为nil),而不是覆盖
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
// do setup stuff here, reset content etc etc.
}
并在视图实际出现在屏幕上之前重置(已加载的)视图
其他信息:
a) 您不需要将视图设置为零。系统会帮你做到这一点。下次访问该视图控制器的view属性时,系统调用loadView
重新创建视图:
如果访问此属性且其当前值为零,则视图
控制器自动调用loadView方法并返回
结果视图。默认的loadView方法尝试加载视图
从与视图控制器关联的nib文件(如果有)
b) 这一切归结为ios5中有关窗口rootViewController
属性的行为。在iOS 5中,这两个方面并不等同:
self.window.rootViewController = newController;
vs
前者完全忽略了方向,后者则没有
为了使事情变得更加复杂,如果一个人不覆盖加载视图,而是让系统自动创建一个空的UIView,并且只在视图中修改该视图,那么内存警告不会自动将视图设置为nil并释放它-docs:
魔法。取决于是否重写该方法。我真的无法用任何方式来测试这一点
案例1-覆盖的loadView
:触发内存警告将调用
didReceiveMemoryWarning
和viewDidUnload
案例2-无loadView
:仅在模拟器中触发内存警告调用
didReceiveMemoryWarning
,但不调用viewDidUnload
我会说,手动添加视图
干杯。谢谢你的建议——但不幸的是,当系统将视图设置为nil(视图控制器响应内存不足警告)时,这不起作用。我明白了。尽管如此,我在测试时观察到,将视图设置为nil并在同一事件循环中切换rootViewController实际上导致了方向未传播到视图控制器的问题。仅在窗口中设置rootViewController不会引起任何问题。因此,也许使用
viewDidUnload
进行内存处理,并在视图中执行其他操作会更好?@k:再次感谢。即使它们不在同一事件循环中发生(例如内存警告),这仍然是一个问题。我甚至不知道如何解决这个问题,因为这不仅仅是不调用旋转事件的问题——即使我手动调用它们,屏幕实际上也不会旋转。我不明白你在iOS 5中应该如何做到这一点。我今天再次关注你的问题,因为我真的很想弄清楚那里发生了什么(对于我自己的项目也是如此)。问题:可以重新创建整个视图控制器吗?还是保留它,然后重新创建视图?@k,看起来像是将window.rootViewController=newController
更改为两行removeFromSuperview
/addSubview
修复了我的所有问题。奇怪,非常感谢你!
[self.window.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)];
[self.window addSubview:newController.view];
The default implementation releases the view only if it determines that it is safe to do so.