XCode 4.5/iOS6: проблема ориентации с моим iPad-приложением в ландшафтном режиме

Я только что открыл свой проект iPad на XCode 4.5. Мое приложение предназначено для работы в ландшафтном режиме. Он отлично работает на предыдущих версиях XCode. Но на XCode 4.5 он поворачивается на 90 ° (четверть оборота) с пустой областью в правой части экрана (и мое представление имеет правильный размер, но выходит из экрана). Это выглядит так:

The view (red) rotated of 90° and going of the screen in landscape mode

Я проверил следующие сообщения, но не помог:

проблема ориентации в ios6

ios6 Проблема с ротацией из пейзажного режима в портрет

Установить ориентацию в альбомный режим в xcode 4.5 GM IOS 6

У кого-нибудь была эта проблема?

Любая помощь будет оценена!

Ответ 1

Спасибо всем за ваши ответы. Я наконец нашел решение.

Сначала убедитесь, что все ваши изображения запуска имеют правильную ориентацию и правильный размер в целевом сводном меню (синий значок вашего проекта = > target = > summary = > прокручивает внизу); если размер или ориентация неверны, вы получите предупреждение об изображении запуска, которое не установлено должным образом.

До сих пор у меня был проект с этой структурой (старый способ XCode):

  • AppDelegate.h и .m
  • RootViewController.h и .m
  • a MainWindow-Iphone.xib и MainWindow-iPad.xibRootViewController, связанным в Interface Builder, см. снимок экрана ниже с желто-коричневым значком (с квадратом внутри) относительно RootViewController)

Ниже снимок экрана, как это выглядело:

My old project structure

И вот что такое код в приложении applicationDidFinishLaunching: мой AppDelegate:

- (void)applicationDidFinishLaunching:(UIApplication *)application {  

     [window addSubview:[rootViewController view]];
     [window makeKeyAndVisible];

}

То, что я сделал, - это быть ближе к структуре, которую вы получаете при создании пустого проекта с XCode 4.5. Следовательно:

  • Я удалил MainWindow.xib и MainWindow-iPad.xib и теперь создал свое окно программно (яснее и лучше, чтобы убедиться, что он соответствует размеру любого экрана)
  • Я удалил базовые имена "Main nib file base name" и "Main nib file base name (iPad)", которые были определены в моем Info.plist (и установлены в MainWindow.xib и MainWindow-iPad.xib)
  • Я добавил пустые RootViewController_iPhone.xib и RootViewController_iPad.xib
  • Я изменил код в моем методе applicationDidFinishLaunching следующим образом:

    - (void)applicationDidFinishLaunching:(UIApplication *)application {    
    
    NSLog(@"applicationDidFinishLaunching");
    
     self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    
    if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) {
        self.rootViewController = [[RootViewController alloc] initWithNibName:@"RootViewController_iPhone" bundle:nil];
    } else {
        self.rootViewController = [[RootViewController alloc] initWithNibName:@"RootViewController_iPad" bundle:nil];
    }
    
    self.window.rootViewController = self.rootViewController;
    
    [self.window makeKeyAndVisible];
    

    }

И теперь все работает отлично! Ориентация правильная на iPad! И это намного яснее, чем раньше:) Мне даже не пришлось менять устаревшие методы, например

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation

Кстати, чтобы убедиться, что все ваши представления будут полноэкранными (на iPhone 5), убедитесь, что ваши представления настроены на режим "Масштабирование для заполнения" в Interface Builder и нажимается "Autoresize subviews". Если некоторые из ваших представлений не масштабируются в полноэкранном режиме, это, вероятно, связано с порядком, в котором вы создаете свои контроллеры/представления (супервизор отправляет уведомление в свои подпрограммы только тогда, когда он создается (супервизор)). Чтобы это легко решить, просто добавьте следующий код в - (void)viewDidLoad method:

CGRect screenBounds = [[UIScreen mainScreen] bounds];
    [self.view setFrame:CGRectMake(0,0,screenBounds.size.width,screenBounds.size.height)];

или используйте:

[self presentModalViewController:myViewController animated:TRUE];

вместо:

[self.view.superview addSubview:myViewController.view];

presentModalViewController действительно отправляет уведомление об изменении размера в подзаголовки.

Надеюсь, это поможет!

Ответ 2

Убедитесь, что вы также устанавливаете window.rootViewController. У меня была такая же проблема, но эта строка исправила это для меня:

MainViewController *mainView = [[MainViewController alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
window.rootViewController = mainView;

Ответ 3

У меня была аналогичная проблема в приложении, которое я обновил. Я не нашел его документированным, но, похоже, произошли изменения. Я обнаружил, что новое окно, похоже, не знает о вращении или размере, пока оно не станет ключевым и видимым. Мне удалось перенести настройку рамки сразу после makeKeyAndVisible, и все сработало. Надеюсь, это поможет вам.

Ответ 4

[[yourViewController view] setFrame:CGRectMake(0.0, 0.0, 1024.0, 768.0)];
[[yourViewController view] setTransform:CGAffineTransformTranslate(CGAffineTransformMakeRotation(0.5*M_PI),128.0,128.0)];

Ответ 5

Если вы используете раскадровки, один простой взлом - это использовать метод loadView. Он вызывается перед viewDidLoad. Просто перейдите на свою раскадровку и удалите связанный с ней вид, так как вы собираетесь его программным образом создать в loadView. Затем вернитесь в класс контроллера вида и скопируйте следующий код:

- (void)loadView
{
    // You can adjust the view size and location here. If using full screen use the following code. If you have a tab bar for example and also want to account for the top default iPad bar, use: CGRectMake(0, 20, 1024, 699) instead.
    UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 1024, 748)]; 
    view.backgroundColor = [UIColor whiteColor];
    view.autoresizesSubviews = NO;

    self.view = view;
}

Ответ 6

Несколько простых шагов по порядку решают эту проблему для вас.

Во-первых, в AppDelegate.m проверьте, добавляете ли вы rootViewController в качестве подвид. То есть вместо этого

- (void)applicationDidFinishLaunching:(UIApplication *)application {  

 [window addSubview:[navigationController view]];
 [window makeKeyAndVisible];

 }

сделайте что-нибудь подобное

- (void)applicationDidFinishLaunching:(UIApplication *)application {  

 window.rootViewController = navigationController;
 [window makeKeyAndVisible];

 }

если вы устанавливаете контроллер навигации в качестве контроллера корневого представления.

Во-вторых, если вам нужно получить контроль над методами поворота в вашем навигационном контроллере navigationController, создайте категорию для UINavigationController следующим образом:

#import "UINavigationController+Rotation.h"

@implementation UINavigationController (Rotation)

- (BOOL)shouldAutorotate {

    BOOL result = self.topViewController.shouldAutorotate;

    return result;
}

- (NSUInteger)supportedInterfaceOrientations {

    return self.topViewController.supportedInterfaceOrientations;
}

@end

Теперь эти два метода ориентации для iOS 6 вверх

- (BOOL) shouldAutorotate и
  - (NSUInteger) supportedInterfaceOrientations

вызывается в ваших классах.

Это необходимо, потому что более старые методы вращения, такие как

- (BOOL) shouldAutorotateToInterfaceOrientation: (UIInterfaceOrientation) interfaceOrientation

устарели от iOS 6.

Итак, вам нужно будет реализовать их в своих контроллерах вида; что-то вроде этого:

-(BOOL)shouldAutorotate
    {
        return YES;
    }

-(NSUInteger)supportedInterfaceOrientations
{
    return UIInterfaceOrientationMaskAll;
}

если вы хотите, чтобы ваш контроллер просмотра вращался и поддерживал все ориентации.

Другие маски ориентации:

  • UIInterfaceOrientationMaskPortrait
  • UIInterfaceOrientationMaskLandscapeLeft
  • UIInterfaceOrientationMaskLandscapeRight
  • UIInterfaceOrientationMaskPortraitUpsideDown
  • UIInterfaceOrientationMaskLandscape и
  • UIInterfaceOrientationMaskAllButUpsideDown