2013-12-06 3 views
1

У меня есть старое приложение, которое все еще живет на iTunes, написанное на iOS 5. Я хотел бы обновить его для запуска на ios 6 и 7. Все было хорошо до сих пор, и я обновили мой код, чтобы использовать ARC. Однако, пытаясь сохранить ту же философию авторотации, я продолжаю ударять по кирпичной стене. Я уже проверил относительные темы в SO как:willAnimateRotationToInterfaceOrientation не вызывается ios6/7

Forcing landscape and autorotate in iOS 7,

Autorotate in iOS 6 has strange behaviour

и после аналогичной теме я нашел это:

iOS 6 Autorotation Problems and Help

, которые приводят меня сделать следующие:

Я установил rootViewController в пределах m у AppDelegate так:

self.preloadingViewController = [[PreloadingViewController alloc] initWithNibName:@"PreloadingViewController" bundle:nil]; 
self.window.rootViewController = self.preloadingViewController; 

Я поставил:

- (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window{ 
return UIInterfaceOrientationMaskAllButUpsideDown; 

}

в моей AppDelegate. Я перекрываться shouldAutorotate и supportedInterfaceOrientations в SuperViewController (родителя с точки зрения наследования) всех UIViewControllers моего приложения (в том числе PreloadingViewController упоминалось выше):

- (BOOL)shouldAutorotate{ 
    return YES; 
} 

- (NSUInteger)supportedInterfaceOrientations{ 
    return UIInterfaceOrientationMaskAllButUpsideDown; 
} 

и в каждом ребенке UIViewController, я переопределить

- (void) willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration 

с кодом для компоновки элементов ui желательным образом для портретной и альбомной ориентации.

Наконец файл PLIST мое приложение под

поддерживаемым интерфейсом ориентации

содержит:

Портрет (нижняя кнопка домой), Пейзаж (левую кнопку дома), Пейзаж (правая кнопка дома)

все ориентации, которые я хочу поддержать.

Тем не менее, хотя для каждого изменения ориентации на моем корневом контроллере вызываются supportedInterfaceOrientations и shouldAutorotate, willAnimateRotationToInterfaceOrientation никогда не вызывается. Я даже переоценил shouldAutomaticallyForwardRotationMethods в своем SuperViewController, чтобы вернуть ДА, но безрезультатно.

Что я здесь делаю неправильно? Есть идеи? Я даже считал, что старые xibs типа ios5 вызывают проблему, но я не думаю, что это так.

Заранее спасибо.

+0

Ур viewcontroller видимый? –

+0

willAnimateRotationToInterfaceOrientation: метод больше не вызывается для невидимых контроллеров просмотров. Поэтому, если ваш контроллер просмотра представляет другой, который принимает на себя, только один из них услышит эти уведомления. –

+0

rootViewController не отображается. Хотя я заметил, что только rootViewController получает уведомление об изменениях в ориентации, его 'willAnimateRotationToInterfaceOrientation' никогда не вызывается. –

ответ

2

Поскольку мой RootViewController был единственным, получая его shouldAutorotate и supportedInterfaceOrientations методов называется, я решил зарегистрировать любой другой контроллер представления, чтобы получить уведомление о любых UIDeviceOrientationDidChangeNotification.

[NSNotificationCenter defaultCenter] addObserver:self 
              selector:@selector(orientationChanged:) 
               name:UIDeviceOrientationDidChangeNotification 
               object:nil]; 

- (void)orientationChanged:(NSNotification *)notification 
{ 
    NSLog(@"Orientation changed!"); 
    [self layoutForOrientation:[[UIDevice currentDevice] orientation]]; 
} 

В моем layoutForOrientation: методе я обращался управляет ориентации UIView в.

Однако, хотя я действительно получал UIDeviceOrientationDidChangeNotification уведомления нормально, на мой взгляд ориентация будет на самом деле не изменится, чтобы соответствовать текущей ориентации, то есть, если новая ориентация была, скажем, UIInterfaceOrientationLandscapeRight, ориентация вид будет оставаться в UIInterfaceOrientationPortrait и его дочерние виды получат повернутый на 90 градусов. Это, конечно, выглядело не так. Вытащив много волос, я решил отказаться от этого маршрута.

Вместо этого я установил, что мой rootViewController является UINavigationController, и пусть он нажимает на него последовательные UIViewControllers. Поскольку я не хотел, чтобы в моем приложении была видимая панель навигации, я установил свойство navigationBarHidden навигационного контроллера в значение YES. Таким образом, метод willAnimateRotationToInterfaceOrientation вызывается на каждом UIViewController, который в настоящее время находится в верхней части стека контроллеров навигационного контроллера, и соответствующие его элементы управления представлением и представлением корректно вращаются для желаемых ориентаций.

Это работает, потому что большинство контроллеров моего представления поддерживают ориентацию интерфейса в соответствии с маской: UIInterfaceOrientationMaskAllButUpsideDown, поведение по умолчанию для iPhone. Должен ли я поддерживать разные ориентации, мне пришлось бы подклассифицировать UINavigationController и переопределить supportedInterfaceOrientations и shouldAutorotate, чтобы включить поддержку желаемых ориентаций для контроллера верхнего уровня навигационного стека, согласно примеру проекта Apple: AlternateViews.

3

В iOS 6 путь willAnimateRotationToInterfaceOrientation называется измененным.

Использование:

- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration 
{ 
    [super willRotateToInterfaceOrientation:toInterfaceOrientation duration:duration]; 

    // Something 
} 

- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation 
{ 
    [super didRotateFromInterfaceOrientation:fromInterfaceOrientation]; 

    // Something 
} 

в вашем rootController.

EDIT:

Новый main.m

#import <UIKit/UIKit.h> 
#import "yourAppDelegate.h" 

int main(int argc, char *argv[]) 
{ 
    @autoreleasepool { 
     return UIApplicationMain(argc, argv, nil, NSStringFromClass([yourAppDelegate class])); 
    } 
} 
+0

Не могли бы вы объяснить, как изменился вызовAnimateRotationToInterfaceOrientation? Я добавил методы, которые вы предложили в свой rootController, но они все еще не вызываются. –

+0

Эти методы следует называть ... Позвольте мне подумать ... У меня были некоторые проблемы в прошлом, связанные с переходом от старых к новым версиям. Является ли ваш файл main.m тем, который я написал в моем EDIT? – Beppe

+0

Мое main.m не похоже на ваше редактирование. Я обновил его с изменениями, которые вы предложили, но без реального эффекта. Спасибо, в любом случае. –

0

Реализуйте этот метод, вернуть YES за то, что вам нужно.

-(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation

+0

Этот метод устарел в ios6 и далее. Я реализовал его для поддержки iOS5 и ранее. –