私のアプリには複数のビューがあり、一部のビューはポートレートとランドスケープの両方をサポートする必要がありますが、他のビューはポートレートのみをサポートする必要があります。したがって、プロジェクトの概要では、すべての方向をすべて選択しました。
以下のコードは、iOS 6より前の特定のView Controllerで横向きモードを無効にするために機能しました。
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
ShouldAutorotateToInterfaceOrientationはiOS6で廃止されたため、上記を次のように置き換えました。
-(NSUInteger)supportedInterfaceOrientations{
return UIInterfaceOrientationMask.Portrait;
}
ビューが表示されるときにこのメソッドは正しく呼び出されます(ブレークポイントを設定してこれを保証できます)が、ポートレートモードのマスクのみを返すという事実に関係なく、インターフェイスは引き続きランドスケープモードに回転します。私は何を間違えていますか?
現在、ビューごとに異なる向きの要件を持つアプリを構築することは不可能のようです。プロジェクトの概要で指定された方向のみを順守しているようです。
INavigationControllerをルートウィンドウコントローラーとしてを使用している場合、itsshouldAutorotate
&supportedInterfaceOrientations
が呼び出されます。
ITabBarControllerなどを使用しているかどうかを確認します。
そのため、すべきことは、Navigation/Tabbar Controllerをサブクラス化し、そのshouldAutorotate
&supportedInterfaceOrientations
メソッドをオーバーライドすることです。
appDelegate.mでこのコードを変更してみてください
// self.window.rootViewController = self.navigationController;
[window setRootViewController:navigationController];
これは完全な答えです
iOS 6ではshouldAutorotateToInterfaceOrientationが呼び出されない
XD
私の場合、UINavigationControllerとView Controllerが内部にあります。 UINavigationControllerをサブクラス化する必要があり、Portraitのみをサポートするには、このメソッドを追加します。
- (NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskPortraitUpsideDown;
}
そのため、UINavigationControllerサブクラスでは、現在のtopViewControllerでサポートされている方向を確認する必要があります。
- (NSUInteger)supportedInterfaceOrientations
{
return [[self topViewController] supportedInterfaceOrientations];
}
私が見つけた1つのことは、あなたがまだしている古いアプリケーションを持っているかどうかです
[window addSubView:viewcontroller.view]; //This is bad in so may ways but I see it all the time...
次のように更新する必要があります。
[window setRootViewController:viewcontroller]; //since iOS 4
これを行うと、オリエンテーションが再び機能し始めます。
IOS6の最適な方法は、レイウェンダリッヒチームによる「チュートリアルによるiOS6」に具体的に記載されています- http://www.raywenderlich.com/ ほとんどの場合、UINavigationControllerをサブクラス化するよりも優れています。
IOS6を使用して、初期ビューコントローラーとして設定されたUINavigationControllerを含むストーリーボードを使用しています。
//AppDelegate.m-このメソッドは、残念ながらiOS6以前では使用できません
- (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window{
NSUInteger orientations = UIInterfaceOrientationMaskAllButUpsideDown;
if(self.window.rootViewController){
UIViewController *presentedViewController = [[(UINavigationController *)self.window.rootViewController viewControllers] lastObject];
orientations = [presentedViewController supportedInterfaceOrientations];
}
return orientations;
}
//MyViewController.m-各UIViewControllerでサポートする向きを返します
- (NSUInteger)supportedInterfaceOrientations{
return UIInterfaceOrientationMaskPortrait;
}
他の人が述べたように、UINavigationControllerを使用していて、さまざまなビューをカスタマイズする場合、UINavigationControllerをサブクラス化し、これらの2つのコンポーネントがあることを確認します。
@implementation CustomNavigationController
// -------------------------------------------------------------------------------
// supportedInterfaceOrientations:
// Overridden to return the supportedInterfaceOrientations of the view controller
// at the top of the navigation stack.
// By default, UIViewController (and thus, UINavigationController) always returns
// UIInterfaceOrientationMaskAllButUpsideDown when the app is run on an iPhone.
// -------------------------------------------------------------------------------
- (NSUInteger)supportedInterfaceOrientations
{
return [self.topViewController supportedInterfaceOrientations];
}
// -------------------------------------------------------------------------------
// shouldAutorotate
// Overridden to return the shouldAutorotate value of the view controller
// at the top of the navigation stack.
// By default, UIViewController (and thus, UINavigationController) always returns
// YES when the app is run on an iPhone.
// -------------------------------------------------------------------------------
- (BOOL)shouldAutorotate
{
return [self.topViewController shouldAutorotate];
}
次に、ポートレートのみのビューに次のものを含めます。
- (NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskPortrait;
}
そして、すべてのビューで、逆さまを除いてすべてです:
- (NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskAllButUpsideDown;
}
基本的に上記の誰かが述べたように、しかしより詳細に:
このクラス(.mファイル)に次のコードを追加して、ポートレートモードのままにします。
(BOOL)shouldAutorotate
{
return NO;
}
(NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskPortrait;
}
これは私のために働いた
UINavigationController
やUITabbarController
をサブクラス化するのではなく、カテゴリを作成するのが最善の方法だと思います
uINavigationController + Rotation.h
#import <UIKit/UIKit.h>
@interface UINavigationController (Rotation)
@end
uINavigationController + Rotation.m
#import "UINavigationController+Rotation.h"
@implementation UINavigationController (Rotation)
-(BOOL)shouldAutorotate
{
return [[self.viewControllers lastObject] shouldAutorotate];
}
-(NSUInteger)supportedInterfaceOrientations
{
return [[self.viewControllers lastObject] supportedInterfaceOrientations];
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
return [[self.viewControllers lastObject] preferredInterfaceOrientationForPresentation];
}
@end
すべてのコントローラーにこのカテゴリーをインポートさせ、これが魅力のように機能するようにしてください。コントローラーを回転させずに、回転する別のコントローラーを押すこともできます。
このコードは私のために働いた:
-(BOOL)shouldAutorotate {
return YES;
}
-(NSUInteger)supportedInterfaceOrientations {
return UIInterfaceOrientationMaskAll;
}
iPhone/iPadアプリの向き 自分の答えを確認する
UITabBarController内でUINavigationControllersを使用しているため、切り取りと貼り付けだけでは機能しませんでしたが、ここでの回答は正しい方向を示しています。したがって、AppDelegate.mの私のバージョンはこのようなもので、UITabBarController内のUITabBarControllers、UINavigationControllers、またはUINavigationControllersで機能します。他のカスタムコンテインメントコントローラーを使用している場合は、ここに追加する必要があります(これはちょっと残念です)。
- (UIViewController*)terminalViewController:(UIViewController*)viewController
{
if ([viewController isKindOfClass:[UITabBarController class]])
{
viewController = [(UITabBarController*)viewController selectedViewController];
viewController = [self terminalViewController:viewController];
}
else if ([viewController isKindOfClass:[UINavigationController class]])
{
viewController = [[(UINavigationController*)viewController viewControllers] lastObject];
}
return viewController;
}
- (NSUInteger)application:(UIApplication *)application
supportedInterfaceOrientationsForWindow:(UIWindow *)window
{
NSUInteger orientations = UIInterfaceOrientationMaskPortrait;
UIViewController* viewController = [self terminalViewController:window.rootViewController];
if (viewController)
orientations = [viewController supportedInterfaceOrientations];
return orientations;
}
注意すべきもう1つの重要な点は、UIViewControllerサブクラスでsupportedInterfaceOrientationsをオーバーライドする必要があることです。そうしないと、Info.plistで指定したものがデフォルトになります。
UINavigationController
を使用している場合、shouldAutorotate
のサブクラスにsupportedInterfaceOrientations
およびUINavigationController
を実装する必要があります。
これらは2つのステップで制御できます。shouldAutorotate
がYESを返し、その後supportedInterfaceOrientations
を返します。とてもいい組み合わせです。
この例では、CoverFlowViewとPreviewViewを除くほとんどのビューはPortraitです。 CoverFlowViewはPreviewViewに転送されます。PreviewViewはCoverFlowCViewの回転を追跡します。
@implementation MyNavigationController
-(BOOL)shouldAutorotate
{
if ([[self.viewControllers lastObject] isKindOfClass:NSClassFromString(@"PreviewView")])
return NO;
else
return YES;
}
-(NSUInteger)supportedInterfaceOrientations
{
if ([[self.viewControllers lastObject] isKindOfClass:NSClassFromString(@"CoverFlowView")])
return UIInterfaceOrientationMaskAllButUpsideDown;
else
return UIInterfaceOrientationMaskPortrait;
}
...
@end
私のソリューション:UINavigationController
をサブクラス化し、window.rootViewController
として設定します
階層の最上位のビューコントローラーが方向を制御します。いくつかのコード例: subclassed UINavigationController
shouldAutorotate
メソッドを追加してみてください
あなたと同じ状況です。あなたはすでに答えを受け入れましたが、とにかく別の答えを追加すると思いました。これが、回転システムの新しいバージョンが機能することを理解する方法です。ルートView Controllerは、呼び出される唯一のView Controllerです。理由は、子View Controllerではビューを回転させることはあまり意味がないことだと思う、とにかくルートView Controllerのフレーム内にとどまるからだ。
それで、何が起こるか。最初にshouldAutorotate
が呼び出されますルートView Controller上。 NO
が返された場合、すべてが停止します。 YES
が返された場合、supportedInterfaceOrientations
メソッドが呼び出されます。このメソッドおよびでInfo.plistまたはアプリケーションデリゲートからサポートされているグローバルな向きでインターフェイスの向きが確認されると、ビューが回転します。回転の前に、shouldAutomaticallyForwardRotationMethods
メソッドが照会されます。 YES
(デフォルト)の場合、すべての子はwill
およびdidRotateTo...
メソッドと親(そしてそれらは順番に子に転送します)。
私の解決策(より雄弁なものがあるまで)は、supportedInterfaceOrientations
メソッドの間に最後の子View Controllerを照会し、その値を返すことです。これにより、一部の領域を回転させながら、他の領域をポートレートのみに維持できます。私はそれが壊れやすいことを理解していますが、イベント呼び出しやコールバックなどで物事を複雑にすることを伴わない別の方法は見当たりません。
まず、アプリをオンリーモードで動作させるには、UIInterfaceOrientationMaskLandscape
を返す必要があります。ポートレートモードのみを維持したい場合は、正しく処理しています。
Info.plistにUISupportedInterfaceOrientations
キーを追加し、アプリが保持する予定のインターフェイスの向きの値を割り当てます。
また、自動回転を完全に回避したい場合は、shouldAutoRotate
からfalseを返す必要があります。ただし、ここからtrueを返し、supportedInterfaceOrientations
メソッドで正しい方向を指定することをお勧めします。