Проблема с ориентацией устройства iOS 6

У меня есть 2 контроллера представления. Я хочу, чтобы 1-й контроллер просмотра был только в портретном режиме, а 2-й контроллер просмотра должен поддерживать все ориентации. Пожалуйста помогите.

В классе AppDelegate мой код:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];

    self.viewController = [[[ViewController alloc] initWithNibName:@"ViewController" bundle:nil] autorelease];
    UINavigationController * navController = [[UINavigationController alloc] initWithRootViewController:self.viewController];
    self.window.rootViewController = self.viewController;
  //  [self.window addSubview:navController.view];
    [self.window makeKeyAndVisible];   
    return YES;
}
- (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window{
    NSLog(@"supportedInterfaceOrientationsForWindow");
    return  UIInterfaceOrientationMaskAllButUpsideDown;
}

1-й код ViewController:

-(BOOL)shouldAutorotate
{
    return NO;
}


-(NSUInteger)supportedInterfaceOrientations
{
    return UIInterfaceOrientationMaskPortrait;
}
// Tell the system which initial orientation we want to have
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation {
    return UIInterfaceOrientationMaskPortrait;
}

Второй код ViewController:

-(NSUInteger)supportedInterfaceOrientations
{
    return UIInterfaceOrientationMaskAllButUpsideDown;
}

-(BOOL)shouldAutorotate
{
    return YES;
}

// Tell the system which initial orientation we want to have
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation {
    return UIInterfaceOrientationMaskAllButUpsideDown;
}

Что я проверяю, так это то, что метод «shouldAutorotate» не вызывается для 1-го и 2-го ViewController.

Ваша быстрая помощь будет очень ценна. Спасибо. Кашиф


person Kashif Ilyas    schedule 20.09.2012    source источник


Ответы (3)


Попробуйте установить supportInterfaceOrientations для второго UIViewController следующим образом:

- (BOOL) shouldAutorotate
{
    return YES;
}

-(NSUInteger)supportedInterfaceOrientations
{
    return UIInterfaceOrientationMaskLandscapeRight; // add any other you want
}

Кроме того, включите только портрет в том же методе в 1-м UIViewController.

Возможно, вам нужно включить эти ориентации также в настройках проекта, которые должен поддерживать второй UIViewController.


[изменить #1: добавлен пример приложения]

Вот пример приложения, которое, надеюсь, решит вашу проблему.

AppDelegate.h

#import <UIKit/UIKit.h>

@class FirstViewController;

@interface AppDelegate : UIResponder <UIApplicationDelegate>

@property (strong, nonatomic) UIWindow *window;

@property (strong, nonatomic) FirstViewController *viewController;

@end

AppDelegate.m

#import "AppDelegate.h"

#import "FirstViewController.h"

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    // Override point for customization after application launch.
    self.viewController = [[FirstViewController alloc] initWithNibName:@"FirstViewController" bundle:nil];
    self.window.rootViewController = self.viewController;
    [self.window makeKeyAndVisible];
    return YES;
}

- (void)applicationWillResignActive:(UIApplication *)application
{
    // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
    // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
}

- (void)applicationDidEnterBackground:(UIApplication *)application
{
    // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 
    // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
}

- (void)applicationWillEnterForeground:(UIApplication *)application
{
    // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.
}

- (void)applicationDidBecomeActive:(UIApplication *)application
{
    // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
}

- (void)applicationWillTerminate:(UIApplication *)application
{
    // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
}

@end

FirstViewController.h

#import <UIKit/UIKit.h>

@interface FirstViewController : UIViewController

- (IBAction)goToSecondViewController:(id)sender;

@end

FirstViewController.m

#import "FirstViewController.h"
#import "SecondViewController.h"

@interface FirstViewController ()

@end

@implementation FirstViewController

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];

    if (self)
    {
        // Custom initialization
    }

    return self;
}

- (void)viewDidLoad
{
    [super viewDidLoad];
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
}

-(BOOL)shouldAutorotate
{
    return NO;
}

-(NSUInteger)supportedInterfaceOrientations
{
    return UIInterfaceOrientationMaskAll;
}

- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
    return UIInterfaceOrientationMaskPortrait;
}

- (IBAction)goToSecondViewController:(id)sender
{
    SecondViewController *svc = [[SecondViewController alloc] initWithNibName:@"SecondViewController" bundle:nil];
    [self presentViewController:svc animated:NO completion:nil];
}

@end

SecondViewController.h

#import <UIKit/UIKit.h>

@interface SecondViewController : UIViewController

- (IBAction)goToFirstViewController:(id)sender;

@end

SecondViewController.m

#import "SecondViewController.h"

@interface SecondViewController ()

@end

@implementation SecondViewController

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];

    if (self)
    {
        // Custom initialization
    }

    return self;
}

- (void)viewDidLoad
{
    [super viewDidLoad];
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
}

-(NSUInteger)supportedInterfaceOrientations
{
    return UIInterfaceOrientationMaskAll;
}

-(BOOL)shouldAutorotate
{
    return YES;
}

- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
    return UIInterfaceOrientationLandscapeLeft;
}

- (IBAction)goToFirstViewController:(id)sender
{
    [self dismissViewControllerAnimated:NO completion:nil];
}

@end

FirstViewController.xib

FirstViewController.xib

SecondViewController.xib

SecondViewController.xib

person uerceg    schedule 20.09.2012
comment
У меня есть портретная, альбомная левая и альбомная правая ориентация в файле проекта info.plist. Я также разместил свой код, пожалуйста, помогите мне. - person Kashif Ilyas; 20.09.2012
comment
Хорошо. Вы должны вернуть UIInterfaceOrientationMaskPortrait из метода supportInterfaceOrientations в классе, который владеет вашим 1-м UIViewController и UIInterfaceOrientationMaskLandscapeRight | UIInterfaceOrientationMaskLandscapeLeft из того же метода в классе, которому принадлежит второй UIViewController. - person uerceg; 20.09.2012
comment
Кроме того, проверьте в Interface Builder, когда вы нажимаете на файл xib, который вы создали для 2-го UIViewController, что для его ориентации установлено значение «Пейзаж». - person uerceg; 20.09.2012
comment
Владельцем 1-го viewController является NavControllerViewController.so, согласно вам, я поместил UIInterfaceOrientationMaskPortrait в метод supportInterfaceOrientations. Точно так же владельцем 2-го ViewController является 1-й ViewController. Теперь я разместил UIInterfaceOrientationMaskLandscapeRight | UIInterfaceOrientationMaskLandscapeLeft в первом контроллере представления. Но никакого успеха. - person Kashif Ilyas; 20.09.2012
comment
Я внес правку №1 в свой ответ. Попробуйте это и дайте мне знать, если это сработало для вас. - person uerceg; 21.09.2012
comment
Привет, я попробовал ваше решение №1, но оно все еще вращается. Я также хочу, чтобы мой контроллер просмотра оставался в портретной ориентации. - person NicTesla; 21.09.2012
comment
Что еще вращается? В моем примере я только что сделал 1-й UIViewController, который остается только в портретном режиме, а 2-й UIViewController можно вращать в любом направлении. Когда я запускаю это приложение, 1-й UIViewController находится ТОЛЬКО в портретном режиме. Второй UIViewController может вращаться в любом направлении, но это всего лишь реализация. Вы можете ограничить его направлениями, которые вы хотите. - person uerceg; 21.09.2012
comment
@uerceg, ваше решение в порядке, потому что вы представляете второй контроллер просмотра. Но если мы собираемся «нажать» второй контроллер представления, то ожидаемое поведение не будет достигнуто. Я хочу «подтолкнуть» мой второй контроллер просмотра, а не «представить», пожалуйста, помогите в этом отношении. - person Kashif Ilyas; 21.09.2012
comment
Или, другими словами, если я изменю ваш код с: - (IBAction)goToSecondViewController:(id)sender { SecondViewController *svc = [[SecondViewController alloc] initWithNibName:@SecondViewController bundle:nil]; [self presentViewController: svc анимированный: НЕТ завершения: ноль]; } to - (IBAction)goToSecondViewController:(id)sender { SecondViewController *svc = [[SecondViewController alloc] initWithNibName:@SecondViewController bundle:nil]; [собственный pushViewController:svc анимированный:НЕТ]; } тогда вы получите тот же неверный вывод, что и я. - person Kashif Ilyas; 22.09.2012
comment
из вашего кода ориентация успешно меняется, но не может изменить кадр. Не могли бы вы сказать мне, где я отстаю - person Sumit Sharma; 10.05.2013

Согласно вашему описанию, контроллер первого вида вставлен в контроллер навигации. Ваше определение метода shouldAutorotate и supportedInterfaceOrientations абсолютно правильно. Во время изменения ориентации ваш навигационный контроллер должен вращаться только и не будет запускать ваш первый контроллер представления (дочерний элемент навигационного контроллера) shouldAutorotate. Таким образом, вам нужно category navigationController в вашем контроллере представления или в отдельном файле и импортировать в него, где это необходимо. Код, как показано ниже, для категории UINavigation Controller.

.h файл имеет этот код

    @interface UINavigationController (autoRotate)

-(BOOL)shouldAutorotate;
- (NSUInteger)supportedInterfaceOrientations;

@end

.m файл имеет этот код

  #import "UINavigationController+autoRotate.h"

@implementation UINavigationController (autoRotate)

-(BOOL)shouldAutorotate
{
    return [[self.viewControllers lastObject] shouldAutorotate];
}

-(NSUInteger)supportedInterfaceOrientations
{
    return [[self.viewControllers lastObject] supportedInterfaceOrientations];
}

Если вы пишете категорию в отдельном файле, вам нужно импортировать файл .h в ваши первый и второй контроллеры представления как #import "UINavigationController+autoRotate"

person Mani    schedule 29.03.2013

простое решение:

реализовать : - (NSUInteger)supportedInterfaceOrientations

по запросу от AppDelegate.m

- (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window

более подробно уже ответил здесь: iOS 6 альбомная и портретная ориентация

person yunas    schedule 05.02.2013