7

My app has about 10 different UIViewControllers, just one of which I want to switch to landscape mode if the device is rotated. (All the rest, I want to keep in portrait.)

In order to implement rotation on that one view, I needed to implement its controller's 'shouldAutorotate' method and return YES. Since this view is accessed via a navigation controller, I also needed to create a subclass of UINavigationController that implements 'shouldAutorotate' and return YES.

This solution works, but too well. I find that all of the UIViewControllers I push onto my subclass of UINavigationController respond to rotation, even if I implement 'shouldAutorotate' and return NO. (Remember: I only want one particular UIViewController to respond to rotation, not every one in the navigation controller's stack.)

So, my question is: how do I best do this? All the solutions I can come up with seem 1) cumbersome, and 2) worse, don't seem to work.

Thanks very much.

4

4 に答える 4

2

UINavigationController を実装すると、このクラスは、スタックにプッシュされるすべての子 viewController を制御する親になります。したがって、RootViewController は、自動回転に対して「はい」または「いいえ」と言う唯一のコントローラーです。子ビュー コントローラーの自動回転に Yes を渡している場合でも、それらはカウントされません。

これが UINavigationController の性質です。それを変更するには、次の 2 つの選択肢があります。

1-手動で操作します。これには、いくつかの面倒なコードを実行する必要があります。

2- UINavigationController との互換性が高まるように設計を変更します。回転する必要がある単一のビューは、NavController をホストするビューである RootViewController (Navigation Root View Controller ではありません。名前は同じですが、まったく異なります) によって呼び出される必要があります。デバイスが回転すると、NavController がビューまたは他のビューにプッシュされます。

3- これも機能しますが、MVC の概念に違反するため推奨されませんが、NavController が通知をリッスンできる方法です。回転することができ、また回転すべきである特定の子ビューは、通知をキャストできます (たとえば、rotateMe など)。

私が言ったように、それは動作しますが、MVC モデルに違反します -- これは Apple にとっては問題ありませんが、プログラミングの観点からは推奨されません。

どちらかについてさらに説明が必要な場合は、お知らせください。

于 2011-10-01T16:39:13.450 に答える
1

これを行うには、ルート ビュー コントローラー (これは UITabBarController の可能性があります) を用意し、その viewDidLoad メソッドで回転イベントをサブスクライブします。

[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
[[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(didRotate:)
                                                      name:@"UIDeviceOrientationDidChangeNotification" 
                                                      object:nil];

次に、didRotate: メソッドで、回転が発生したときにどのビュー コントローラーが表示されているか、および電話の向きを確認します。

- (void) didRotate:(NSNotification *)notification { 
UIDeviceOrientation orientation = [[UIDevice currentDevice] orientation];

/*
    DEVICE JUST ROTATED TO PORTRAIT MODE

 orientation == UIDeviceOrientationFaceUp ||
 orientation == UIDeviceOrientationFaceDown

 */
if(orientation == UIDeviceOrientationPortrait) {





/*
    DEVICE JUST ROTATED TO LANDSCAPE MODE
 */
}else if(orientation == UIInterfaceOrientationLandscapeLeft ||
        orientation == UIInterfaceOrientationLandscapeRight) {






}

}

その didRotate: 内で、表示されているviewControllerを見て、そこから必要なことを行うことができます。

特定のView Controllerが表示され、電話が横向きに回転しているときに、モーダルView Controllerを横向きモードで表示します。他のビュー コントローラーが表示されている場合は、イベントを無視します。

viewWillAppear メソッドで、モーダル ビュー コントローラーを強制的に横向きモードで表示します。必要に応じて、このコードを誰にでも渡すことができます。

お役に立てれば。

デイブ

于 2010-06-28T15:30:27.167 に答える
1

[[navController topViewController] isKindOfClass:[RotatingViewController class]] の場合にのみ、ナビゲーション コントローラーのサブクラスで YES を返します。

于 2011-09-01T17:29:12.790 に答える
0

私はあなたがそれをしている方法を使った例を見ましたが、それを正しく動作させることができませんでした。私はリンゴの例からそれを行うためのより良い方法を見つけました。基本的に、presentModalViewControllerを実装し、別のビューを作成します。UIKitは基本的な回転アニメーションを実行し、ビュー間でフェードします。回転したビューをデリゲートクラスとして実装して、呼び出し元のクラスにコールバックして閉じ、方向を更新できるようにする必要があります。

- (void)orientationChanged:(NSNotification *)notification
{
    // We must add a delay here, otherwise we'll swap in the new view
    // too quickly and we'll get an animation glitch
    NSLog(@"orientationChanged");
    [self performSelector:@selector(updateLandscapeView) withObject:nil afterDelay:0];
}

次に、横向きの画面を表示するには:

- (void)updateLandscapeView
{
PortraitView *portraitView = [[PortraitView alloc] init];
portraitView.delegate = self;
UIDeviceOrientation deviceOrientation = [UIDevice currentDevice].orientation;
if (UIDeviceOrientationIsLandscape(deviceOrientation) && !isShowingLandscapeView)
{
    [self presentModalViewController: portraitView animated:YES];
    isShowingLandscapeView = YES;
    }
else if (deviceOrientation == UIDeviceOrientationPortrait && isShowingLandscapeView)
{
    [self dismissModalViewControllerAnimated:YES];
    isShowingLandscapeView = NO;
    }
[portraitView release];
}
于 2010-05-15T05:31:56.440 に答える