【发布时间】:2015-07-17 19:48:24
【问题描述】:
我正在使用这个观察者:UIDeviceOrientationDidChangeNotification 来检测用户何时更改设备方向。当方向更改为横向时,我会呈现一个新的UIViewController,或者当他将其更改回纵向时将其关闭。
当用户开始快速旋转设备数次时,我的问题就开始了,然后应用程序变得疯狂,直到我收到此错误:
警告:尝试展示不在窗口层次结构中的视图!`。
等到动画结束然后更改旋转的最佳方法是什么?
这是我在 Prepresenting view controller 上使用的:
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
[self beginDeviceOrientationListener];
}
- (void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
- (void)beginDeviceOrientationListener
{
[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(orientationChanged:) name:UIDeviceOrientationDidChangeNotification object:[UIDevice currentDevice]];
}
- (void)orientationChanged:(NSNotification *)notification
{
UIDevice *device = notification.object;
switch (device.orientation)
{
case UIDeviceOrientationLandscapeLeft:
case UIDeviceOrientationLandscapeRight:
{
TheViewControllerToPresent *viewController = [[TheViewControllerToPresent alloc] init];
[self presentViewController:viewController animated:YES completion:nil];
[[UIDevice currentDevice] setValue:[NSNumber numberWithInteger:UIInterfaceOrientationLandscapeRight] forKey:@"orientation"];
[[UIApplication sharedApplication] setStatusBarOrientation:[[[UIDevice currentDevice] valueForKey:@"orientation"] integerValue] animated:YES];
[[UIApplication sharedApplication] setStatusBarHidden:NO withAnimation:UIStatusBarAnimationSlide];
}
break;
default:
break;
}
}
这就是我在呈现的视图控制器上使用的:
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
[self beginDeviceOrientationListener];
}
- (void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
- (void)beginDeviceOrientationListener
{
[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(orientationChanged:) name:UIDeviceOrientationDidChangeNotification object:[UIDevice currentDevice]];
}
- (void)orientationChanged:(NSNotification *)notification
{
UIDevice *device = notification.object;
switch (device.orientation)
{
case UIDeviceOrientationPortrait:
{
[self dismissViewControllerAnimated:YES completion:nil];
[[UIDevice currentDevice] setValue:[NSNumber numberWithInteger:UIInterfaceOrientationPortrait] forKey:@"orientation"];
[[UIApplication sharedApplication] setStatusBarOrientation:[[[UIDevice currentDevice] valueForKey:@"orientation"] integerValue] animated:YES];
}
break;
default:
break;
}
}
【问题讨论】:
-
你为什么要设置
[UIDevice orientation]?这是什么可怕的黑客行为? -
嗯,它实际上工作得很好,为什么要破解?我应该改用什么?
-
[UIDevice orientation]是只读的,这是有原因的。 hack 是您正在使用反射 (setValue:) 访问它,绕过readonly状态。如果您不想使用控制器具有的默认旋转支持,您可以在呈现的控制器的视图上使用transform。
标签: ios objective-c uiviewcontroller uideviceorientation