IOS 6にアップデートしているiPhoneアプリで、回転の問題が発生しています。 UITabBarController
と16UINavigationCotrollers
があります。ほとんどのサブビューはポートレートまたはランドスケープで機能しますが、一部はポートレートのみです。 iOS 6では、物事は回転してはいけないときに回転しています。
TabBarControllerをサブクラス化して、現在のnavigationControllerで選択されたviewControllerのsupportedInterfaceOrienations
を返すようにしました。
- (NSUInteger)supportedInterfaceOrientations{
UINavigationController *navController = (UINavigationController *)self.selectedViewController;
return [navController.visibleViewController supportedInterfaceOrientations];
}
これは私を近づけました。ビューコントローラは、表示されているときに位置がずれて回転することはありませんが、横向きでタブを切り替えると、サポートされていなくても新しいタブは横向きになります。
理想的には、アプリは現在表示されているViewControllerのサポートされている方向にのみ存在します。何か案は?
これらのメソッドをオーバーライドするUITabBarController
をサブクラス化します。
-(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// You do not need this method if you are not supporting earlier iOS Versions
return [self.selectedViewController shouldAutorotateToInterfaceOrientation:interfaceOrientation];
}
-(NSUInteger)supportedInterfaceOrientations
{
return [self.selectedViewController supportedInterfaceOrientations];
}
-(BOOL)shouldAutorotate
{
return YES;
}
これらのメソッドをオーバーライドするUINavigationController
をサブクラス化します。
-(NSUInteger)supportedInterfaceOrientations
{
return [self.topViewController supportedInterfaceOrientations];
}
-(BOOL)shouldAutorotate
{
return YES;
}
次に、回転させたくないこれらのメソッドをviewControllersに実装します。
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
-(BOOL)shouldAutorotate
{
return NO;
}
-(NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskPortrait;
}
また、回転させたいviewControllerの場合:
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
}
-(NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskAllButUpsideDown;
}
-(BOOL)shouldAutorotate
{
return YES;
}
TabbarControllerは、アプリウィンドウのRootviewControllerとして追加する必要があります。デフォルトの向きをサポートする予定の場合、iPhoneでは逆さま以外はすべてデフォルトです。他に何もする必要はありません。逆さまをサポートしたい場合、または別のオリエンテーションをサポートしたくない場合は、アプリデリゲートやinfo.plistで適切な値を設定する必要があります。
ナビゲーションスタック内の一部のViewコントローラーがすべての向きをサポートし、一部は縦向きのみをサポートするという問題がありましたが、UINavigationController
がアプリでサポートされるすべての向きを返していたため、この小さなハックが役に立ちました。これが意図された動作なのか、それとも何なのかわかりません
@implementation UINavigationController (iOS6OrientationFix)
-(NSUInteger) supportedInterfaceOrientations {
return [self.topViewController supportedInterfaceOrientations];
}
@end
私はそのようなものの方が良いと思います(カテゴリーメソッドとして)
-(NSUInteger) supportedInterfaceOrientations {
if([self.topViewController respondsToSelector:@selector(supportedInterfaceOrientations)])
{
return [self.topViewController supportedInterfaceOrientations];
}
return UIInterfaceOrientationMaskPortrait;
}
これにより、メソッドが確実に実装されます。このチェックを行っておらず、メソッドが実装されていない場合(iOS5 envのように)、アプリはクラッシュするはずです!
すべてのViewControllerの回転を有効または無効にする場合は、UINavigationController
をサブクラス化する必要はありません。代わりに以下を使用してください:
-(NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window
AppDelegate
で。
アプリですべての方向をサポートする予定であるが、PARENT View Controllerで異なる方向(たとえばUINavigationController
スタック)をサポートする場合は、次を使用する必要があります
-(NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window
AppDelegate
から、PARENT ViewControllerの次のメソッドと組み合わせます。
- (BOOL)shouldAutorotate
そして
- (NSUInteger)supportedInterfaceOrientations
ただし、同じナビゲーションスタック(私のように)内の異なるCHILDREN ViewControllerで異なる方向設定を計画している場合は、ナビゲーションスタック内の現在のViewControllerを確認する必要があります。
UINavigationController
サブクラスで次を作成しました。
- (BOOL)shouldAutorotate
{
return YES;
}
- (NSUInteger)supportedInterfaceOrientations
{
int interfaceOrientation = 0;
if (self.viewControllers.count > 0)
{
DLog(@"%@", self.viewControllers);
for (id viewController in self.viewControllers)
{
if ([viewController isKindOfClass:([InitialUseViewController class])])
{
interfaceOrientation = UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskPortraitUpsideDown;
}
else if ([viewController isKindOfClass:([MainViewController class])])
{
interfaceOrientation = UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskPortraitUpsideDown;
}
else
{
interfaceOrientation = UIInterfaceOrientationMaskAllButUpsideDown;
}
}
}
return interfaceOrientation;
}
子ViewControllerから表示されたViewControllerの回転設定を制御できなくなったため、ナビゲーションスタックに現在あるViewControllerを何らかの方法でインターセプトする必要があります。それが私がしたことです:)。お役に立てば幸いです。