it-swarm.com.ru

Поддержка различной ориентации только для одного представления 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)];
}
}
27
Alex G

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

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

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

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

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

@end 
19
ChavirA

В 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

6
Nekto

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

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

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

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

2
pkc456

У меня есть:

TabbarController -> NavigationController -> ViewController -> ViewController

Я Subclassed 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;
}

0
Kurt57

Я искал решение в течение нескольких часов! 

Так что после внедрения необходимых методов везде. 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 я соединил взгляды с этим переходом (показывая):

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"];

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

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

0
Alex Cio

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];
}

Не забудьте сбросить маску перед выходом из этого контроллера 

Обратите внимание, что если вы используете UINavigationController или UITabBarController, см. https://stackoverflow.com/a/28220616/821994 как обойти это

0
Aleksey Mazurenko