Это реальный ответ. Когда приложение запускается, его ориентация неизвестна. Он использует shouldAutorotateToInterfaceOrientation и supportInterfaceOrientations, чтобы решить, какую ориентацию выбрать.
Посмотрите, как я запускаю пример приложения в симуляторе iPhone 5.0 и поворачиваю его, используя код ниже и «Поддерживаемые ориентации интерфейса» со всеми 4 возможными ориентациями:
20:44:08.218 RotationTestApp Supported orientation: Portrait
20:44:08.222 RotationTestApp Supported orientation: Portrait (upside-down)
20:44:08.225 RotationTestApp Supported orientation: Landscape (home button on the right)
20:44:08.225 RotationTestApp Supported orientation: Landscape (home button on the left)
20:44:08.226 RotationTestApp shouldAutorotateToInterfaceOrientation: YES (current device orientation: UIDeviceOrientationUnknown, interface orientation wants: UIInterfaceOrientationPortrait)
20:44:08.237 RotationTestApp shouldAutorotateToInterfaceOrientation: YES (current device orientation: UIDeviceOrientationUnknown, interface orientation wants: UIInterfaceOrientationPortrait)
20:44:08.239 RotationTestApp shouldAutorotateToInterfaceOrientation: YES (current device orientation: UIDeviceOrientationUnknown, interface orientation wants: UIInterfaceOrientationPortrait)
20:44:08.240 RotationTestApp shouldAutorotateToInterfaceOrientation: YES (current device orientation: UIDeviceOrientationUnknown, interface orientation wants: UIInterfaceOrientationPortrait)
20:44:09.817 RotationTestApp shouldAutorotateToInterfaceOrientation: YES (device orientation: UIDeviceOrientationLandscapeLeft)
20:44:09.833 RotationTestApp shouldAutorotateToInterfaceOrientation: YES (device orientation: UIDeviceOrientationLandscapeLeft)
20:44:11.030 RotationTestApp shouldAutorotateToInterfaceOrientation: YES (device orientation: UIDeviceOrientationPortraitUpsideDown)
20:44:11.040 RotationTestApp shouldAutorotateToInterfaceOrientation: YES (device orientation: UIDeviceOrientationPortraitUpsideDown)
20:44:12.599 RotationTestApp shouldAutorotateToInterfaceOrientation: YES (device orientation: UIDeviceOrientationLandscapeRight)
20:44:12.609 RotationTestApp shouldAutorotateToInterfaceOrientation: YES (device orientation: UIDeviceOrientationLandscapeRight)
20:44:13.301 RotationTestApp shouldAutorotateToInterfaceOrientation: YES (device orientation: UIDeviceOrientationPortraitUpsideDown)
Я видел много фрагментов кода, но ни один из них не работает достаточно широко (iPad и iPhone, iOS 5.0 +).
Вместо того, чтобы возиться с try-this-try-that, поместите следующее в ваш корневой vc:
#define ToNSString_BEGIN(T) \
NSString* T##ToNSString(T valueParameter) { \
switch (valueParameter) {
#define ToNSString_VALUE(value) \
case value: return @#value
#define ToNSString_END(T) \
} \
return @"(unknown)"; \
}
// NSString* UIInterfaceOrientationToNSString(UIInterfaceOrientation);
ToNSString_BEGIN(UIInterfaceOrientation);
ToNSString_VALUE(UIInterfaceOrientationPortrait); // 1
ToNSString_VALUE(UIInterfaceOrientationPortraitUpsideDown); // 2
ToNSString_VALUE(UIInterfaceOrientationLandscapeLeft); // 3
ToNSString_VALUE(UIInterfaceOrientationLandscapeRight); // 4
ToNSString_END (UIInterfaceOrientation);
// NSString* UIDeviceOrientationToNSString(UIDeviceOrientation);
ToNSString_BEGIN(UIDeviceOrientation);
ToNSString_VALUE(UIDeviceOrientationUnknown); // 0
ToNSString_VALUE(UIDeviceOrientationPortrait); // 1
ToNSString_VALUE(UIDeviceOrientationPortraitUpsideDown); // 2
ToNSString_VALUE(UIDeviceOrientationLandscapeLeft); // 3
ToNSString_VALUE(UIDeviceOrientationLandscapeRight); // 4
ToNSString_VALUE(UIDeviceOrientationFaceUp); // 5
ToNSString_VALUE(UIDeviceOrientationFaceDown); // 6
ToNSString_END (UIDeviceOrientation);
// Change this custom method to alter auto-rotation behavior on all supported iOS versions and platforms.
- (BOOL)allowAutoRotate:(UIInterfaceOrientation)interfaceOrientation
{
NSUInteger interfaceOrientationAsMask = (1<<interfaceOrientation);
return interfaceOrientationAsMask & [self supportedInterfaceOrientations];
}
// Reads from the project's-Info.plist
- (NSUInteger)supportedInterfaceOrientations
{
static NSUInteger orientationsResult;
if (!orientationsResult) {
NSArray *supportedOrientations = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"UISupportedInterfaceOrientations"];
for (id orientationString in supportedOrientations) {
if ([orientationString isEqualToString:@"UIInterfaceOrientationPortrait"]) {
orientationsResult |= UIInterfaceOrientationMaskPortrait;
NSLog(@"Supported orientation: Portrait");
} else if ([orientationString isEqualToString:@"UIInterfaceOrientationPortraitUpsideDown"]) {
orientationsResult |= UIInterfaceOrientationMaskPortraitUpsideDown;
NSLog(@"Supported orientation: Portrait (upside-down)");
} else if ([orientationString isEqualToString:@"UIInterfaceOrientationLandscapeRight"]) {
orientationsResult |= UIInterfaceOrientationMaskLandscapeRight;
NSLog(@"Supported orientation: Landscape (home button on the left)");
} else if ([orientationString isEqualToString:@"UIInterfaceOrientationLandscapeLeft"]) {
orientationsResult |= UIInterfaceOrientationMaskLandscapeLeft;
NSLog(@"Supported orientation: Landscape (home button on the right)");
} else {
NSLog(@"Unrecognized orientation '%@' in mainBundle plist, key UISupportedInterfaceOrientations", orientationString);
}
}
}
return orientationsResult;
}
// iOS 6+ (not yet used in 6.0.1)
- (BOOL)shouldAutorotate
{
UIDeviceOrientation interfaceOrientationFromDevice = [UIDevice currentDevice].orientation;
BOOL result = [self allowAutoRotate:interfaceOrientationFromDevice];
NSString *currentDeviceOrientation = UIDeviceOrientationToNSString(interfaceOrientationFromDevice);
NSLog(@"shouldAutorotate: %s (current orientation %@)", result ? "YES" : "NO", currentDeviceOrientation);
return result;
}
// iOS 2.0 - 5.1 (iOS 6+ deprecated, 6.0.1 still works)
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
NSString* orientationString;
UIDeviceOrientation interfaceOrientationFromDevice = [UIDevice currentDevice].orientation;
if ((int)interfaceOrientation != (int)interfaceOrientationFromDevice) {
orientationString = [NSString stringWithFormat:@"current device orientation: %@, interface orientation wants: %@",
UIDeviceOrientationToNSString(interfaceOrientationFromDevice),
UIInterfaceOrientationToNSString(interfaceOrientation)
];
} else {
orientationString = [NSString stringWithFormat:@"device orientation: %@", UIDeviceOrientationToNSString(interfaceOrientationFromDevice)
];
}
BOOL result = [self allowAutoRotate:interfaceOrientation];
NSLog(@"shouldAutorotateToInterfaceOrientation: %s (%@)",
result ? "YES" : "NO",
orientationString);
return result;
}
Существует все еще острая проблема анимации перехода, не использующей текущую ориентацию. Я предполагаю, что создание подкласса каждого VC и установка некоторой ориентации на делегат push / notify на pop будет правильным решением.
Также важно:
shouldAutorotateToInterfaceOrientation не работает
tabBarController и навигационные контроллеры в ландшафтном режиме, эпизод II