Поддержка различной ориентации только для одного вида iOS 6

Я хочу повернуть ТОЛЬКО один из моих представлений в своем приложении, либо влево, либо вправо. Все мои другие взгляды находятся в портретном режиме, и я установил приложение для поддержки только портретного режима. С изменением ориентации в iOS 6 я не уверен, как это сделать. Я попробовал следующее ниже. Может ли кто-нибудь сказать мне, что я делаю неправильно? Спасибо!

-(BOOL)shouldAutorotate {
return YES;
}

-(NSUInteger)supportedInterfaceOrientations {
return UIInterfaceOrientationMaskLandscapeLeft | UIInterfaceOrientationMaskLandscapeRight;
}

-(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{

return UIInterfaceOrientationMaskLandscapeRight | UIInterfaceOrientationMaskLandscapeLeft;
} 

Я также пробовал:

-(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
[[NSNotificationCenter defaultCenter] addObserver:self
                                         selector:@selector(didRotate:)
                                            name:UIDeviceOrientationDidChangeNotification
                                           object:nil];
return YES;//UIInterfaceOrientationMaskLandscapeRight | UIInterfaceOrientationMaskLandscapeLeft;
} 


 -(void)didRotate:(NSNotification *)notification {
 UIDeviceOrientation orientation = [[notification object] orientation];

if (orientation == UIDeviceOrientationLandscapeLeft) {
    [theImage setTransform:CGAffineTransformMakeRotation(M_PI / -2.0)];
    [self.view setTransform:CGAffineTransformMakeRotation(M_PI / 2.0)];
} else if (orientation == UIDeviceOrientationLandscapeRight) {
    [theImage setTransform:CGAffineTransformMakeRotation(M_PI / -2.0)];
    [self.view setTransform:CGAffineTransformMakeRotation(M_PI / -2.0)];
} else if (orientation == UIDeviceOrientationPortraitUpsideDown) {
    [theImage setTransform:CGAffineTransformMakeRotation(M_PI / -2.0)];
    [self.view setTransform:CGAffineTransformMakeRotation(M_PI / -2.0)];
} else if (orientation == UIDeviceOrientationPortrait) {
    [theImage setTransform:CGAffineTransformMakeRotation(M_PI / 2.0)];
    [self.view setTransform:CGAffineTransformMakeRotation(M_PI / 2.0)];
}
}

Ответ 1

Это сработало для меня Как заставить ориентацию UIViewController на портретную ориентацию в iOS 6

Создайте новую категорию из UINavigationController, переопределяя методы вращения:

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

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

- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
    return [self.topViewController preferredInterfaceOrientationForPresentation];
}

@end 

Привет!

Ответ 2

В iOS 6 есть изменения относительно обработки поворотов просмотра. Поддерживаются только ориентации, определенные в приложениях Info.plist. Даже если вы возвращаете другие.

Попробуйте выбрать все ориентации, которые поддерживаются в вашем проекте.

Обработка поворотов просмотра

В iOS 6 ваше приложение поддерживает ориентацию интерфейса, определенную в вашем приложении Info.plist. Контроллер вида может переопределить метод supportedInterfaceOrientations, чтобы ограничить список поддерживаемых ориентаций. Как правило, система называет этот метод только на контроллере корневого представления окна или контроллере представления, представленном для заполнения всего экрана; Контроллеры дочерних представлений используют часть окна, предоставленную для них контроллером родительского представления, и больше не участвуют в принятии решений о том, какие вращения поддерживаются. Пересечение маски ориентации приложения и маски ориентации диспетчера представлений используются для определения ориентации, с которой может поворачиваться контроллер представления.

Вы можете переопределить preferredInterfaceOrientationForPresentation для контроллера вида, который предназначен для представления полного экрана в определенной ориентации.

В iOS 5 и ранее класс UIViewController отображает только представления в портретном режиме. Чтобы поддерживать дополнительные ориентации, вы должны переопределить метод shouldAutorotateToInterfaceOrientation: и вернуть YES для любых ориентаций, поддерживаемых вашим подклассом. Если параметры авторезизации ваших представлений настроены правильно, это может быть все, что вам нужно сделать. Тем не менее, класс UIViewController предоставляет дополнительные перехваты для выполнения дополнительных действий по мере необходимости. Как правило, если ваш контроллер просмотра предназначен для использования в качестве контроллера детского представления, он должен поддерживать все ориентации интерфейса.

Когда происходит поворот для контроллера видимого вида, во время вращения вызывают методы willRotateToInterfaceOrientation:duration:, willAnimateRotationToInterfaceOrientation:duration: и didRotateFromInterfaceOrientation:. Метод viewWillLayoutSubviews также вызывается после изменения размера представления и размещения его родителем. Если контроллер вида не отображается, когда происходит изменение ориентации, методы вращения никогда не вызываются. Тем не менее, метод viewWillLayoutSubviews вызывается, когда вид становится видимым. Ваша реализация этого метода может вызвать метод statusBarOrientation для определения ориентации устройства.

(C) Apple Docs: UIViewController

Ответ 3

Выполните следующие шаги

  • Создать подкласс UINavigationController, переопределяющий методы вращения.
  • В AppDelegate создайте свойство BOOL islandcape.
  • Когда представление нажато/всплыло/появилось/отклонено, отрегулируйте это значение BOOL.

Пример проекта

Я создал образец проекта для этого, который работает отлично. Загрузите и интегрируйте в свой проект: https://www.dropbox.com/s/nl1wicbx52veq41/RotationDmeo.zip?dl=0

Ответ 4

У меня есть:

TabbarController → NavigationController → ViewController → ViewController

I Подклассифицировано UITabBarController и добавьте....

-(NSUInteger)supportedInterfaceOrientations{
    if (self.selectedIndex >= 0 && self.selectedIndex < 100) {
        for (id vC in [[self.viewControllers objectAtIndex:(unsigned long)self.selectedIndex] viewControllers]) {
            if ([vC isKindOfClass:[CLASS_WHICH_SHOULD_ALLOW class]]) {
                return UIInterfaceOrientationMaskPortrait + UIInterfaceOrientationMaskLandscape;
            }
        }
    }
    
    return UIInterfaceOrientationMaskPortrait;
}

Ответ 5

Я искал решение часами!

Итак, после внедрения необходимых методов повсюду. shouldAutorotate не нужно устанавливать в YES, потому что он уже установлен по умолчанию:

- (NSUInteger)supportedInterfaceOrientations{
    return UIInterfaceOrientationMaskPortrait;
}

- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation{
     return UIInterfaceOrientationPortrait;
}

Когда пришло время показать UIViewController, для которого требуется ориентация, отличная от других представлений, я создал UIStoryboardSegue с этой реализацией внутри:

#import "Showing.h"

@implementation Showing

- (void)perform{
    NSLog(@"Showing");
    UIViewController *sourceVC = self.sourceViewController;
    UIViewController *presentingVC = self.destinationViewController;

    [sourceVC.navigationController presentViewController:presentingVC 
                                                animated:YES 
                                              completion:nil];
}

@end

Внутри UIStoryboard я связал просмотры с этим segue (, показывая):

enter image description here

Это просто важно, вы используете

presentViewController:animated:completion:

И НЕ

pushViewController:animated:

в противном случае ориентация не будет определена снова.


Я пробовал такие вещи, как
[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationPortrait];

ИЛИ этот внутри UIViewController, где ориентация должна измениться, и я также попытался вызвать его внутри моего пользовательского UIStoryboardSegues до presentingViewController и dismissViewController:

[UIViewController attemptRotationToDeviceOrientation];

ИЛИ

NSNumber *numPortrait = [NSNumber numberWithInt:UIInterfaceOrientationPortrait];
[[UIDevice currentDevice] setValue:numPortrait forKey:@"orientation"];

Но никто из них не работал. Конечно, последний пример не должен быть вариантом, потому что если яблоко изменит что-либо из их api, это может вызвать проблемы внутри вашего приложения.

Я также попытался использовать метод AppDelegate и всегда определял ориентацию внутри этого метода после поиска правильного UIInterfaceOrientation фактического visibleViewController, но иногда это случалось при сбое при переключении с одной на другую. Поэтому я все еще удивляюсь, почему это стало настолько сложным, и, похоже, также нет никакой документации, где это объясняется правильно. Даже после эта часть не помогла мне.

Ответ 6

UIViewController + OrientationPermissions.h

@interface UIViewController (OrientationPermissions)
   + (void)setSupportedOrientations:(UIInterfaceOrientationMask)supportedOrientations;
   + (UIInterfaceOrientationMask)supportedOrientations;
@end

UIViewController + OrientationPermissions.m

@implementation UIViewController (OrientationPermissions)
static UIInterfaceOrientationMask _supportedOrientations;

+ (void)setSupportedOrientations:    (UIInterfaceOrientationMask)supportedOrientations {
    _supportedOrientations = supportedOrientations;
}

+ (UIInterfaceOrientationMask)supportedOrientations {
    return _supportedOrientations;
}

@end

В вашем делете UIApplication

- (UIInterfaceOrientationMask)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window {
    return [UIViewController supportedOrientations];
}

Затем на желаемом контроллере представления сделайте что-то вроде

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    [UIViewController setSupportedOrientations:UIInterfaceOrientationMaskAll];
}

Не забудьте маску reset перед тем, как покинуть этот контроллер просмотра

Обратите внимание, что если вы используете UINavigationController или UITabBarController, см. fooobar.com/questions/50988/..., как обходить этот

Ответ 7

Непосредственно работа Пожалуйста, попробуйте. Я решаю через 2 дня

//AppDelegate.m - этот метод недоступен до iOS6, к сожалению

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

if(self.window.rootViewController){
    UIViewController *presentedViewController = [[(UINavigationController *)self.window.rootViewController viewControllers] lastObject];
    orientations = [presentedViewController supportedInterfaceOrientations];
}

return orientations;
}

//MyViewController.m - вернуть любые ориентации, которые вы хотите поддерживать для каждого UIViewController

- (NSUInteger)supportedInterfaceOrientations{
    return UIInterfaceOrientationMaskPortrait;
}