Вращение ведет себя по-разному на iOS6
Я сделал приложение, основанное на табу. Ничто не должно быть в ландшафтном режиме, но пара взглядов. Он работал нормально на iOS5, и я был очень доволен результатом. Однако с iOS6 и без каких-либо проблем, он теперь вращает все взгляды, и последствия не очень приятны.
Поскольку его приложение на основе табуляции, пара представлений, которые мне нужны в ландшафте, - это modalViews. Таким образом, я не возился с табуляцией, и мне нужно было только выбрать портрет в настройке "Поддерживаемые ориентации" на настройках сборки и установить:
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
return (interfaceOrientation == UIInterfaceOrientationLandscapeLeft);
return (interfaceOrientation == UIInterfaceOrientationLandscapeRight);
}
на представлениях, которые мне нужны, пейзаж.
Теперь с iOS6 эти представления также находятся в режиме портрета, независимо от того, что и они не отображают ландшафтный режим, даже если я поворачиваю устройство. Аналогично, если я разрешаю все ориентации на "Поддерживаемые ориентации", все они вращаются, независимо от того, что я накладываю на вышеописанный метод.
Во всех представлениях я не установил флажок "Использовать автоспуск" на раскадровки.
Любая помощь здесь?
* ИЗМЕНИТЬ **
Теперь, когда я это вижу, приложение, которое у меня есть на устройстве, отлично работает. Я установил с промо-кодом, а не с Xcode, только чтобы узнать, есть ли у моих клиентов проблемы или нет. В конце концов, это не так. Проблема остается, хотя.
Ответы
Ответ 1
Самая важная часть документации, которую я нашел для этой проблемы:
Когда пользователь меняет ориентацию устройства, система вызывает это метод на контроллере корневого представления или верхний представленный вид контроллер, который заполняет окно
Чтобы мое приложение полностью работало для авторотации в iOS 6, мне пришлось сделать следующее:
1) Я создал новый подкласс UINavigationController и добавил shouldAutorotate и supportedInterfaceOrientation:
// MyNavigationController.h:
#import <UIKit/UIKit.h>
@interface MyNavigationController : UINavigationController
@end
// MyNavigationController.m:
#import "MyNavigationController.h"
@implementation MyNavigationController
...
- (BOOL)shouldAutorotate {
return YES;
}
- (NSUInteger)supportedInterfaceOrientations {
return UIInterfaceOrientationMaskAll;
}
...
@end
2) В AppDelegate я использовал свой новый подкласс для отображения моего корневого ViewController (это introScreenViewController, подкласс UIViewController) и установил self.window.rootViewController, поэтому он выглядит так:
nvc = [[MyNavigationController alloc] initWithRootViewController:introScreenViewController];
nvc.navigationBarHidden = YES;
self.window.rootViewController = nvc;
[window addSubview:nvc.view];
[window makeKeyAndVisible];
Ответ 2
Это альтернативное решение для iOS6, если вы используете контроллер панели вкладок. Он также показывает, что НЕ требуется переопределять UINavigationController или даже UITabBarController.
В xyzAppDelegate.h добавьте этот интерфейс:
@interface UITabBarController (MyApp)
@end
И в xyzAppDelegate.m добавьте следующие методы:
@implementation UITabBarController (MyApp)
-(BOOL)shouldAutorotate
{
return YES;
}
- (NSUInteger)supportedInterfaceOrientations
{
// your custom logic for rotation of selected tab
if (self.selectedIndex==...) {
return UIInterfaceOrientationMaskAll;
}
else {
return UIInterfaceOrientationMaskPortrait|UIInterfaceOrientationMaskPortraitUpsideDown;
}
}
@end
Также установите контроллер корневого представления для окна приложения:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
...
[self.window setRootViewController:tabBarController];
Ответ 3
Вы устанавливаете rootViewController в делегате? Например,
self.window.rootViewController = self.navigationController;
Когда я тестировал iOS6, он не работал бы должным образом, пока я не сделал это...
Ответ 4
У меня хорошее решение для работы от 5,0 до 6,0. Все вышеперечисленное с помощью
-(BOOL)shouldAutorotate{return [self shouldIRotateAnyiOS];}//iOS6
-(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation{return [self shouldIRotateAnyiOS];}//pre iOS6
-(BOOL)shouldIRotateAnyiOS{
UIInterfaceOrientation interfaceOrientation = [[UIDevice currentDevice] orientation];
//do the rotation stuff
return YES
}
Ответ 5
Вы можете дважды проверить Ориентации интерфейса поддержки
![enter image description here]()
В предыдущей версии это ничего не значит, но теперь влияет на все приложение.
Примечание. Параметр "вверх дном" не работает даже включен или отключен на iOS 6.
Ответ 6
Это то, что работает для меня.
Я создал новый подкласс UINavigationController и добавил shouldAutorotate и supportedInterfaceOrientation:
#import "MyNavigationController.h"
@interface MyNavigationController ()
@end
@implementation MyNavigationController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (BOOL)shouldAutorotate {
return [self.visibleViewController shouldAutorotate];
}
- (NSUInteger)supportedInterfaceOrientations {
return [self.visibleViewController supportedInterfaceOrientations];
}
@end
Затем добавьте это в свой делегат
UINavigationController *nvc = [[MyNavigationController alloc] initWithRootViewController:_viewController];
nvc.navigationBarHidden = NO; // YES if you want to hide the navigationBar
self.window.rootViewController = nvc;
[_window addSubview:nvc.view];
[_window makeKeyAndVisible];
Теперь вы можете добавить это к представлениям, которые вы хотите повернуть во всех ориентациях.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return YES;
}
-(NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskAll;
}
-(BOOL)shouldAutorotate
{
return YES;
}
Или добавьте это в представления, на которые вы хотите пойти только портрет и портретУказанный
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return
(interfaceOrientation == UIInterfaceOrientationPortrait || interfaceOrientation == UIInterfaceOrientationPortraitUpsideDown);
}
- (NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskPortraitUpsideDown ;
}
- (BOOL)shouldAutorotate
{
return YES;
}
Ответ 7
Авторотация изменена в iOS 6.0. Подробнее см. .
Авторизация изменяется в iOS 6. В iOS 6, shouldAutorotateToInterfaceOrientation: метод UIViewController устарел. Вместо этого вы должны использовать supportInterfaceOrientations и shouldAutorotate.
Ответ 8
Есть несколько вещей, которые вам, возможно, придется обрабатывать, чтобы получить эту работу, поскольку с iOS6 изменилась структура авторотации. Структура определения авторотата теперь отменена. Раньше считалось, что контроллер отдельного представления может управлять авторотатом своим решением, но теперь "shouldAutorotate" определяется самым высоким родителем в навигации, который в вашем случае является tabBar.
- Вам нужно убедиться, что в вашем окне установлен rootViewController, а не только как подзаголовок.
- Возможно, вам потребуется подклассифицировать ваш tabBarController для реализации как "supportedInterfaceOrientations", так и "shouldAutorotate".
- Если есть какие-либо viewControllers, которые должны вести себя по-разному, вам нужно будет с помощью своего tabBarController проконсультироваться с ними для ответа на вопрос о том, должны ли они авторотировать.
например:
- (BOOL)shouldAutorotate
{
return self.selectedViewController.shouldAutorotate;
}
и в вашем контроллере просмотра вы должны реализовать shouldAutorotate и принять решение там.
Ответ 9
Этот код, общий для ios5 и ios6
-(void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation duration:(NSTimeInterval)duration {
if (UIInterfaceOrientationIsLandscape(interfaceOrientation)) {
[self performSelector:@selector(setframeLandscap) withObject:nil afterDelay:0.2];
}
else {
[self performSelector:@selector(setframePortrait) withObject:nil afterDelay:0.2];
}
}
-(BOOL)shouldAutorotate {
return YES;
}
Ответ 10
Из документации Apple для shouldAutorotateToInterfaceOrientation:
Вместо этого переопределите методы supportedInterfaceOrientations и preferInterfaceOrientationForPresentation.
http://developer.apple.com/library/ios/#documentation/uikit/reference/UIViewController_Class/DeprecationAppendix/AppendixADeprecatedAPI.html#//apple_ref/occ/instm/UIViewController/shouldAutorotateToInterfaceOrientation:
Ответ 11
Для приложения "То же изображение" на iOS6 мне нужно изменить ориентацию, мой UIViewController никогда не будет проинформирован о его ориентации, это наложение фотографий, вероятно, работает, хорошо работает:
- (void)didRotate: ( NSNotification* )note
{
[self performSelector:@selector(rotateRecalculDiffere) withObject:nil afterDelay:0.3 ];
}
Я делаю точный размер с задержкой вызова. От уведомления легко узнать конечную ориентацию
Ответ 12
Сделал небольшое экспериментирование: принял существующее приложение (которое не будет вращаться в iOS-6, но делалось ранее) и добавило одну строку self.window.rootViewController = navCtlr;
в AppDelegate. Это привело к появлению приложения (по крайней мере, с первого раза) для поворота просто.
Затем, из любопытства, я создал класс RotationCanary и подключил экземпляр этого в self.window.rootViewController. Я запустил приложение и дождался неизбежного "нераспознанного селектора", создав новый метод этого имени в RotationCanary и снова запустил. Новый метод будет вызывать реальный nav ctlr и записывать его ответ перед его возвратом. Это вызвало (раньше, чем я ожидал) следующий журнал:
2012-12-07 13:08:47.689 MyTestApp[53328:c07] System Version is 6.0; Supported versions are 5.0.x to 6.0.x
2012-12-07 13:08:47.691 MyTestApp[53328:c07] Host memory (in bytes) used: 3489513472 free: 803893248 total: 4293406720
2012-12-07 13:08:47.692 MyTestApp[53328:c07] Memory in use by task (in bytes): 23719936
2012-12-07 13:08:47.695 MyTestApp[53328:c07] Creating database
2012-12-07 13:08:47.699 MyTestApp[53328:c07] Item Selected: (null) (null)
2012-12-07 13:08:47.700 MyTestApp[53328:c07] <DetailViewController.m:(27)> Entering Method -[DetailViewController viewDidLoad]
2012-12-07 13:08:47.706 MyTestApp[53328:c07] <SplitContentViewController.m:(57)> Entering Method -[SplitContentViewController viewDidLoad]
2012-12-07 13:08:47.708 MyTestApp[53328:c07] <FamilyMasterViewController.m:(32)> Entering Method -[FamilyMasterViewController viewDidLoad]
2012-12-07 13:08:47.709 MyTestApp[53328:c07] <MasterViewController.m:(41)> Entering Method -[MasterViewController viewDidLoad]
2012-12-07 13:08:47.718 MyTestApp[53328:c07] <FamilyHomeDetailViewController.m:(51)> Entering Method -[FamilyHomeDetailViewController viewDidLoad]
2012-12-07 13:08:47.820 MyTestApp[53328:c07] -[RotationCanary _preferredInterfaceOrientationGivenCurrentOrientation:] - current = 2, result = 2
2012-12-07 13:08:47.821 MyTestApp[53328:c07] -[RotationCanary _existingView] - view = (null)
2012-12-07 13:08:47.824 MyTestApp[53328:c07] -[RotationCanary view] - view = <UILayoutContainerView: 0x9c987f0; frame = (0 0; 768 1024); autoresize = W+H; layer = <CALayer: 0x9c8fa00>>
2012-12-07 13:08:47.825 MyTestApp[53328:c07] -[RotationCanary view] - view = <UILayoutContainerView: 0x9c987f0; frame = (0 0; 768 1024); autoresize = W+H; layer = <CALayer: 0x9c8fa00>>
2012-12-07 13:08:47.826 MyTestApp[53328:c07] -[RotationCanary view] - view = <UILayoutContainerView: 0x9c987f0; frame = (0 0; 768 1024); autoresize = W+H; layer = <CALayer: 0x9c8fa00>>
2012-12-07 13:08:47.827 MyTestApp[53328:c07] -[RotationCanary wantsFullScreenLayout] - result = YES
2012-12-07 13:08:47.827 MyTestApp[53328:c07] -[RotationCanary view] - view = <UILayoutContainerView: 0x9c987f0; frame = (0 0; 768 1024); autoresize = W+H; layer = <CALayer: 0x9c8fa00>>
2012-12-07 13:08:47.830 MyTestApp[53328:c07] -[RotationCanary _tryBecomeRootViewControllerInWindow:] - window = <UIWindow: 0x9c76320; frame = (0 0; 768 1024); opaque = NO; autoresize = RM+BM; layer = <UIWindowLayer: 0x9c76450>>, result = YES
2012-12-07 13:08:47.916 MyTestApp[53328:c07] -[RotationCanary _deepestDefaultFirstResponder] - result = <SignOnViewController: 0x9c942a0>
2012-12-07 13:08:47.916 MyTestApp[53328:c07] Device model: x86_64
Любопытно, что класс никогда не вызывался для выполнения вращения - только во время установки.
Я подозреваю, что Apple использует настройку rootViewController исключительно как способ указать, что приложение было изменено для вращения iOS 6 - в противном случае он не имеет никакой реальной функции.
FWIW: Мне пришло в голову, что вызывающий может использовать respondsToSelector
и пропускать некоторые вызовы, поэтому я добавил реализацию resolveInstanceMethod:
в RotationCanary, чтобы уловить любые такие попытки. Ничего не произошло.