web-dev-qa-db-ja.com

iOS 6 UITabBarControllerは、現在のUINavigationcontrollerでオリエンテーションをサポートしました

IOS 6にアップデートしているiPhoneアプリで、回転の問題が発生しています。 UITabBarControllerと16UINavigationCotrollersがあります。ほとんどのサブビューはポートレートまたはランドスケープで機能しますが、一部はポートレートのみです。 iOS 6では、物事は回転してはいけないときに回転しています。

TabBarControllerをサブクラス化して、現在のnavigationControllerで選択されたviewControllerのsupportedInterfaceOrienationsを返すようにしました。

- (NSUInteger)supportedInterfaceOrientations{

    UINavigationController *navController = (UINavigationController *)self.selectedViewController;
    return [navController.visibleViewController supportedInterfaceOrientations];
}

これは私を近づけました。ビューコントローラは、表示されているときに位置がずれて回転することはありませんが、横向きでタブを切り替えると、サポートされていなくても新しいタブは横向きになります。

理想的には、アプリは現在表示されているViewControllerのサポートされている方向にのみ存在します。何か案は?

17
Ryan

これらのメソッドをオーバーライドする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で適切な値を設定する必要があります。

58
Dean Davids

ナビゲーションスタック内の一部のViewコントローラーがすべての向きをサポートし、一部は縦向きのみをサポートするという問題がありましたが、UINavigationControllerがアプリでサポートされるすべての向きを返していたため、この小さなハックが役に立ちました。これが意図された動作なのか、それとも何なのかわかりません

@implementation UINavigationController (iOS6OrientationFix)

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

@end
5
Mindaugas

私はそのようなものの方が良いと思います(カテゴリーメソッドとして)

-(NSUInteger) supportedInterfaceOrientations {
    if([self.topViewController respondsToSelector:@selector(supportedInterfaceOrientations)])
    {
        return [self.topViewController supportedInterfaceOrientations];
    }
    return UIInterfaceOrientationMaskPortrait;
}

これにより、メソッドが確実に実装されます。このチェックを行っておらず、メソッドが実装されていない場合(iOS5 envのように)、アプリはクラッシュするはずです!

3
Alvise Susmel

すべての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を何らかの方法でインターセプトする必要があります。それが私がしたことです:)。お役に立てば幸いです。

0
Razvan