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