質問

オリエンテーションの変更をサポートするiPadアプリケーション用のネストビュー階層があります。次のように見えます。

UIViewController
    UIView
        - UIView
            - UIImageView (disable rotation)
            - UIImageView
            - UIView (disable rotation)
        - UIView
        - UIView
        ...

他の人が自動回転してサイズを変更できるようにしながら、いくつかのサブビューの方向をロックしたいと思います。これを達成する方法を理解できないようです。

1つのアプローチがサブビューを手動で回転させているようです willAnimateRotationToInterfaceOrientation:. 。 SDKが私が元に戻す回転を実行していることを考えると、それは特に魅力的ではありません。

サブビューやその他の方法の方向変更を単純に無効にして、階層を再構築する方法はありますか?

役に立ちましたか?

解決

オートローテーションは、ビューのuiviewcontrollerによって処理されます(shouldAutorotateToInterfaceOrientation:)、そのため、1つのアプローチは、回転可能なビューが1つのビューコントローラーによって管理されるように階層を配置し、別のビューコントローラーによって回転不可能なビューを管理することです。これらのuiviewcontrollerのルートビューはどちらも、ウィンドウ/スーパービューに追加する必要があります。

ここでの微妙さは、同じレベルで2つのビューコントローラーのビューがある場合です(つまり、byを追加しました addSubview:)、最初のビューコントローラーのみ(通常はウィンドウの rootViewControllershouldAutorotateToInterfaceOrientation: メッセージ。

私はこのアプローチを使用して、メインビューはそうではありませんが、回転するツールバーを実現しました。

Appleの技術Q&A QA1688(「なぜ私のuiviewcontrollerがデバイスで回転しないのですか?」) この問題について少し話します。


iOS 6の更新:

オートローテーションは現在使用されています UIViewController's shouldAutorotatesupportedInterfaceOrientations 方法。 shouldAutorotate 戻り値 YES デフォルトでは、以外のビューコントローラーは rootViewController ウィンドウの直接サブビューは、とにかく回転コールバックを受信しません。


iOS 6のサンプルコード:

「シングルビューアプリケーション」テンプレートを使用して新しいプロジェクトを作成し、「ストーリーボードの使用」が確認されていることを確認します。提供されたものを使用します ViewController 回転ビューコントローラーとしてのクラス(必要に応じて名前を変更してください!)、2つ目を作成します UIViewController サブクラスが呼び出されました NonRotatingViewController. 。このビューコントローラーは回転コールバックを受信することさえありませんが、完全性と明確さのために、次のコードをに追加します NonRotatingViewController.m:

- (BOOL)shouldAutorotate
{
    return NO;
}

の中に MainStoryboard ファイル、新しいビューコントローラーオブジェクトをドラッグして、そのクラスをに設定します NonRotatingViewController, 、およびストーリーボードIDを「non -rotatingVc」に設定します。そこにいる間に、回転ビューコントローラービューの背景色をClear(この展示の下に追加されます)をクリアに変更し、各ビューにラベルを追加します。の AppDelegate.m, 、次のコードを追加します。

#import "NonRotatingViewController.h"

// ...
// ...

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    // Override point for customization after application launch.
    UIStoryboard *mainStoryboard = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil];
    NonRotatingViewController *nonRotatingVC = [mainStoryboard instantiateViewControllerWithIdentifier:@"NonRotatingVC"];
    [self.window addSubview:nonRotatingVC.view];
    return YES;
}

これは、非回転ビューコントローラーをインスタンス化し、そのビューをウィンドウに直接追加するだけです(この時点でウィンドウのNB rootViewController すでにストーリーボードで設定されています)。

プロジェクトを実行します。デバイスを回転させ、1つのラベルが回転するのを見て、もう1つのラベルが静止しているのを見て驚かせます!


サンプルコードPre iOS 6:

私はこれを新しいプロジェクトで行いました - 新しいビューベースのアプリケーションでは問題ありません。 2つの新しいビューコントローラーを追加します。 RotatingViewControllerNonRotatingViewController. 。それぞれのペン先の中には、ビューを回転させるかどうかを説明するためにラベルを追加しました。次のコードを追加します。

'RotatingViewController.m'

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    return YES;
}


'NonRotatingViewController.m'

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    if (interfaceOrientation == UIInterfaceOrientationPortrait) {    // Or whatever orientation it will be presented in.
        return YES;
    }
    return NO;
}


'AppDelegate.m'

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    RotatingViewController *rotating = [[RotatingViewController alloc] initWithNibName:@"RotatingViewController" bundle:nil];
    self.rotatingViewController = rotating;
    [rotating release];

    NonRotatingViewController *nonRotating = [[NonRotatingViewController alloc] initWithNibName:@"NonRotatingViewController" bundle:nil];
    self.nonRotatingViewController = nonRotating;
    [nonRotating release];

    [self.window addSubview:self.rotatingViewController.view];
    [self.window insertSubview:self.nonRotatingViewController.view belowSubview:self.rotatingViewController.view];

    [self.window makeKeyAndVisible];

    return YES;
}

これが役立つことを願っています。

他のヒント

これが別の方法です。このコードをviewcontroller viewdidloadに配置するだけです。

    YourAppDelegate *delegate = [[UIApplication sharedApplication] delegate];
        // the view you don't want rotated (there could be a heierarchy of views here):
    UIView *nonRotatingView = [[UIView alloc] initWithFrame:CGRectMake(100,0,30,500)];
    nonRotatingView.backgroundColor = [UIColor purpleColor];

        // make sure self.view and its children are transparent so you can see through to this view that will not be rotated behind self.view.

    [delegate.window insertSubview:nonRotatingView  belowSubview:self.view];

        // you can't put it in the front using:
        //    [delegate.window insertSubview:nonRotatingView aboveSubview:self.view];
        // It will show up the same as before

    // you should declare nonRotatingView as a property so you can easily access it for removal, etc.

この問題を解決する私のアプローチは、 UINotification 自動回転を検出し、逆方向にビューを回転させるには。

ここで完全なコードを見つける:
https://gist.github.com/ffraenz/5945301

- (void)orientationDidChangeNotificationReceived:(NSNotification *)notification
{
    // find out needed compass rotation
    //  (as a countermeasure to auto rotation)
    float rotation = 0.0;

    if (self.interfaceOrientation == UIInterfaceOrientationPortraitUpsideDown)
        rotation = M_PI;
    else if (self.interfaceOrientation == UIInterfaceOrientationLandscapeLeft)
        rotation = M_PI / 2.0;
    else if (self.interfaceOrientation == UIInterfaceOrientationLandscapeRight)
        rotation = M_PI / (- 2.0);

    // rotate compass without auto rotation animation
    //  iOS rotation animation duration is 0.3
    //  this excludes the compassView from the auto rotation
    //  (same effect as in the camera app where controls do rotate and camera viewport don't)
    [UIView animateWithDuration:0.3 animations:^(void) {
        self.compassView.transform = CGAffineTransformMakeRotation(rotation);
    }];
}
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top