100

UINavigationControllerドリルダウン インターフェイスを表示するためにを使用する iPhone アプリがあります。最初の 3 つのビューを縦向きに制限し、最後のビューのみを横向きに回転できるようにする必要があります。4 番目のビューから 3 番目のビューに戻り、4 番目のビューが横向きだった場合、すべてを縦向きに回転させたいと思います。

shouldAutorotateToInterfaceOrientation:iOS 5 では、許可された方向に対して YES を返すように、各ビュー コントローラーで単純に定義しました。View Controller #4 から #3 に戻るときにデバイスが横向きに保持されていた場合でも、縦向きに戻ることを含め、すべてが上記のように機能しました。

iOS 6 では、すべてのビュー コントローラーが横向きに回転し、意図されていないものを壊します。iOS 6のリリースノートには

より多くの責任がアプリとアプリ デリゲートに移行しています。現在、iOS コンテナー ( などUINavigationController) は、自動回転する必要があるかどうかを決定するために、その子に相談しません。[...] システムは、デバイスが回転するたびに、またはビュー コントローラーがフルスクリーン モーダル プレゼンテーション スタイルで表示されるたびに、サポートされているインターフェイスの向きを最上位のフルスクリーン ビュー コントローラー (通常はルート ビュー コントローラー) に問い合わせます。さらに、このView ControllerがshouldAutorotateメソッドからYESを返した場合にのみ、サポートされている向きが取得されます。[...] システムは、アプリのsupportedInterfaceOrientationsForWindow:メソッドによって返された値supportedInterfaceOrientationsと、最上位のフルスクリーン コントローラーのメソッドによって返された値を交差させることによって、向きがサポートされているかどうかを判断します。

そこで、 をサブクラス化UINavigationControllerし、MainNavigationControllerブール値のプロパティlandscapeOKを指定し、これを使用して で許容される向きを返しましたsupportedInterfaceOrientations。次に、各View ControllerのviewWillAppear:メソッドに、次のような行があります

    [(MainNavigationController*)[self navigationController] setLandscapeOK:YES];

MainNavigationController望ましい行動を教えてくれます。

ここで質問があります。ポートレート モードで 4 番目のビューに移動し、電話を裏返すと、回転してランドスケープになります。ここで、戻るボタンを押して、縦向きのみで動作するはずの 3 番目のビューに戻ります。でも逆回転しない。どうすればそれを行うことができますか?

私は試した

    [[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationPortrait]

私の3番目のView ControllerのviewWillAppearメソッドでは、何もしません。これは呼び出すメソッドが間違っているのでしょうか、それとも呼び出す場所が間違っているのでしょうか、それともまったく別の方法ですべてを実装する必要がありますか?

4

15 に答える 15

96

私は同じ問題を抱えていて、自分に合った解決策を見つけました。それを機能させるには、UINavigationControllerに実装するだけでは不十分です。- (NSUInteger)supportedInterfaceOrientationsまた、コントローラー #3 にこのメソッドを実装する必要があります。コントローラー #3 は、コントローラー #4 をポップした後、縦向き専用になる最初のコントローラーです。したがって、UINavigationController に次のコードがあります。

- (BOOL)shouldAutorotate
{
    return YES;
}

- (NSUInteger)supportedInterfaceOrientations
{
    if (self.isLandscapeOK) {
        // for iPhone, you could also return UIInterfaceOrientationMaskAllButUpsideDown
        return UIInterfaceOrientationMaskAll;
    }
    return UIInterfaceOrientationMaskPortrait;
}

ビュー コントローラー #3 で、次を追加します。

- (NSUInteger)supportedInterfaceOrientations
{
    return UIInterfaceOrientationMaskPortrait;
}

ビュー コントローラー #1、#2、および #4 に何も追加する必要はありません。これは私にとってはうまくいきます。

于 2012-10-26T16:25:18.563 に答える
4

@Brian の回答にコメントするほどの評判はないので、ここにメモを追加します。

Brian は、iOS6 は rootViewController に回転制御を与えると述べました。私の構造は次のようになります。

  • UITabBarController
    • UINavigationController
      • UIViewControllers ...
    • UINavigationController
      • UIViewControllers ...

そのため、最初にカスタム UITabBarController にメソッドを追加し、次にカスタム UINavigationController に追加し、最後に特定の UIViewController に追加しました。

UITabBarController と UINavigationController の例:

- (BOOL)shouldAutorotate {
    return [self.viewControllers.lastObject shouldAutorotate];
}

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

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation {
    return [self.viewControllers.lastObject shouldAutorotateToInterfaceOrientation:toInterfaceOrientation];
}

- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation {
    return [self.viewControllers.lastObject preferredInterfaceOrientationForPresentation];
}
于 2013-07-25T15:48:49.487 に答える
3

私自身の質問に部分的に答えたいと思います。viewWillAppear3番目のメソッドで使用されている次のコード行が機能することがわかりましたUIViewController

[[UIDevice currentDevice] 
      performSelector:NSSelectorFromString(@"setOrientation:") 
           withObject:(id)UIInterfaceOrientationPortrait];

しかし、私はこの解決策が本当に好きではありません。これは、Appleのドキュメントによると、デバイスの物理的な向きを表す読み取り専用プロパティに割り当てるためのトリックを使用しています。これは、ユーザーの手で正しい向きにジャンプするようにiPhoneに指示するようなものです。

それは単に機能するので、私はこれを私のアプリに残したいと思っています。しかし、それは正しくないと感じているので、私はクリーンな解決策のために質問を開いたままにしておきたいと思います。

于 2012-09-29T11:13:02.857 に答える
1

これは非常に閲覧数の多いスレッドです。最も簡単な答えだと思うものを追加すると思いました。これは ios8 以降で動作します

-(BOOL)shouldAutorotate
{
    return YES;
}

-(UIInterfaceOrientationMask)supportedInterfaceOrientations{
return UIInterfaceOrientationMaskPortrait;
}

それでおしまい。楽しみ!

ああ、ViewControllers はナビゲーション コントローラーに埋め込まれているので、サブクラス化や構成を行う必要はありません。

于 2016-01-20T07:44:49.163 に答える
0

iOS 6 アプリのポートレートのみを強制したい場合は、メソッドの下の UIViewController サブクラスに追加できます

- (BOOL)shouldAutorotate {
    if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
        return YES;
    } else {
        return NO;
    }
}


- (NSUInteger)supportedInterfaceOrientations {
    if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
        return UIInterfaceOrientationMaskAll;
    } else {
        return UIInterfaceOrientationMaskPortrait;
    }
}
于 2013-04-23T10:45:56.223 に答える
0

1 つを除いて、すべての VC を縦向きにロックしたかったのです。これが私のために働いたものです。

  1. plist ファイルにすべての方向のサポートを追加します。
  2. ルート ビュー コントローラーで、ウィンドウの上にあるビュー コントローラーの種類を検出し、それに従ってアプリの向きをsupportedInterfaceOrientationsメソッドに設定します。たとえば、webview がスタックの最上位にある場合にのみアプリを回転させる必要がありました。rootVC に追加したものは次のとおりです。

    -(NSUInteger)supportedInterfaceOrientations
    {
        UIViewController *topMostViewController = [[Utils getAppDelegate] appNavigationController].topViewController;
        if ([topMostViewController isKindOfClass:[SVWebViewController class]]) {
            return UIInterfaceOrientationMaskAllButUpsideDown;
        }
        return UIInterfaceOrientationMaskPortrait;
    }
    
于 2014-01-24T02:20:13.010 に答える
0

私は同じ種類の問題を解決しました。

を使用しUINavigationControllerてビュー コントローラーをプッシュする場合は、以下のメソッドを設定する必要があります。

extension UINavigationController{

    override open var shouldAutorotate: Bool {

        if topViewController != nil && (topViewController?.isKind(of: LogInViewController.self))!
        {
            return true
        }
        return false
    }

    override open var supportedInterfaceOrientations: UIInterfaceOrientationMask {

        if topViewController != nil && (topViewController?.isKind(of: LogInViewController.self))!
        {
            return .portrait
        }
        return .landscapeRight

    }
    override open var preferredInterfaceOrientationForPresentation: UIInterfaceOrientation {

        if topViewController != nil && (topViewController?.isKind(of: LogInViewController.self))!
        {
            return .portrait
        }
        return .landscapeRight
    }
}

見せたいLoginViewController用途に。UIViewController私の場合、モードで他LoginViewControllerのモードで表示したいと思います。PortraitViewControllerslandscape

于 2017-08-26T05:57:31.917 に答える
-1

この問題を解決するには、次の方法を使用してください

- (NSUInteger)supportedInterfaceOrientations
{
    return UIInterfaceOrientationMaskPortrait;
}

必要な方向のみを返します!!!

于 2012-10-10T19:14:57.003 に答える