Я использую этот наблюдатель: UIDeviceOrientationDidChangeNotification
для обнаружения, когда пользователь меняет ориентацию устройства. Когда ориентация изменилась на альбомную, я представляю новый UIViewController
или отклоняю этот UIViewController
, когда он снова меняет его на портретный.
Моя проблема начинается, когда пользователь начинает вращать устройство несколько раз и быстро, затем приложение сходит с ума, пока я не получаю эту ошибку:
Предупреждение: Попытка представить, чье представление не находится в иерархии окон!`.
Каков наилучший способ дождаться окончания анимации, а затем изменить вращение?
Это то, что я использую в Контроллере представления представления:
- (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]
? что за ужасный хак? - person Sulthan   schedule 07.05.2015[UIDevice orientation]
по какой-то причине доступен только для чтения. Хак заключается в том, что вы обращаетесь к нему с помощью отражения (setValue:
), минуя статусreadonly
. Если вы не хотите использовать поддержку вращения по умолчанию, которую имеют контроллеры, вы можете просто использоватьtransform
в представлении представленного контроллера. - person Sulthan   schedule 07.05.2015