13

私はいくつかのビューコントローラを持つナビゲーションコントローラを持っています。ランドスケープのみをサポートする1​​つの特別なビューコントローラを除いて、すべてのビューコントローラのすべての向きをサポートする必要があります。この特別なビューコントローラは、ナビゲーションスタックの中央に表示されます。私はかなりの研究をしましたが、良い解決策を見つけることができませんでした。ここで私が読んで試みたリンクがあります。UINavigationControllerで1つのビューのみのランドスケープをサポート

http://www.iphonedevsdk.com/forum/iphone-sdk-development/3219-force-landscape-mode-one-view.html#post60435

How to rotate screen to landscape?

How to autorotate from portrait to landscape mode? iPhone - allow landscape orientation on just one viewcontroller http://goodliffe.blogspot.com/2009/12/iphone-forcing-uiview-to-reorientate.html

次の私は特別なビューコントローラを表示するためにpresentModalViewControllerとナビゲーションコントローラを交換しようとするつもりです。次に、特別なビューコントローラ内に新しいナビゲーションビューコントローラを作成して、後続のビューコントローラをプッシュします。

もっと良いアイデアがあれば、教えてください。本当に感謝!

UPDATE:presentModalViewControllerpushViewControllerを交換し、新しいナビゲーションコントローラを作成:私は正常に私は上記の方法を使用しています。

+0

サンプルコードを共有できますか? –

答えて

8

をポップした後、新しいコントローラをプッシュナビゲーションコントローラが同じ方向をサポートする必要がスタックにプッシュ。これは、ポートレートのみをサポートするビューコントローラと、サポートする風景のみをサポートするビューコントローラを持つことができないことを意味します。つまり、同じナビゲーションコントローラのスタック上のすべてのビューコントローラはデリゲートで同じことを返す必要があります:

(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation 

しかし、これに対する簡単な解決策があります!ここでは、ポートレートからランドスケープへの移行の例を示します。ここではそれを行うための手順を示し、それをサポートするコードを以下に示します。

  1. サブナビゲーションコントローラのルートとなる「偽の」ビューコントローラを作成します。このビューコントローラはランドスケープをサポートする必要があります。
  2. 第2のビューコントローラ
  3. は、親ビューコントローラ
  4. からモーダルとして UINavigationControllerインスタンスをプレゼントとしてルートとして「偽」ビューコントローラとあなたの景観ビューコントローラのインスタンスのインスタンスを追加し、 UINavigationControllerの新しいインスタンスを作成します。

まず、このコードで新しいビューコントローラ(FakeRootViewController)を作成します。ここでは

@interface FakeRootViewController : UIViewController 
@property (strong, nonatomic) UINavigationController* parentNavigationController; 
@end 

@implementation FaceRootViewController 
@synthesize parentNavigationController; 
// viewWillAppear is called when we touch the back button on the navigation bar 
(void)viewWillAppear:(BOOL)animated { 
    // Remove our self from modal view though the parent view controller 
    [parentNavigationController dismissModalViewControllerAnimated:YES]; 
} 
(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { 
    return (interfaceOrientation == UIInterfaceOrientationIsLandscape(interfaceOrientation)); 
} 

は、あなたが表示したいビューコントローラを提示するためのコードですランドスケープモード:

(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { 
    return (interfaceOrientation == UIInterfaceOrientationIsLandscape(interfaceOrientation)); 
} 
+1

+50 amazeballs。 – Adam

+0

最後にまっすぐ答え。 – Jeef

0

それはあなたのUINavigationControllerに押し込まれ、各UIViewController

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation 

を実装するのと同じくらい簡単でなければなりません。 1つのUIViewControllerのビューが回転してはならない場合は、具体的な向きのreturn NOを具体的なUIViewControllerにしてください。あなたのUINavigationControllerは、それがそのメソッドを受けてからそのviewControllersをブロックします

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation 

を実装している場合 は、しかしここに落とし穴があります。その場合、あなたはあなたが現在目に見えるビューのshouldAutorotateToInterfaceOrientationを呼び出すために、あなたのUINavigationControllerにこのコードを試みることができる

[[self topViewController] shouldAutorotateToInterfaceOrientation:interfaceOrientation]; 
+3

私はそれが簡単だと思った。あなたはそれを試しましたか?それにはいくつかの問題があります。 1.電話機がポートレートのときに特殊なランドスケープビューをレンダリングすると、電話機をランドスケープにすると、予期せずにビューがポートレートに回転します。 2.最初に特殊なランドスケープビューをレンダリングしてから、電話機をポートレートに回転させてから、特殊なビューを終了して再入力すると、ビューが予期せず回転します。これはナビゲーションコントローラの問題のように思え、Appleがあなたが説明したもののために動作させることを本当に望みます。 –

+0

私はそれを試しました。私はあなたが遭遇している問題は、あなたのアプリケーションに固有のものかもしれないと思います。新しいプロジェクトを開始して、UINavigationControllerの回転問題を特定してから、いくつかの実験を実行してみてください。 – schellsan

0

を使用してtopViewControllerにメッセージを転送する必要があります。私の場合、UITabBarControllerにはUINavigationControllerがありますが、他の場合にはおそらくそれを適用できます。

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation 
{ 
    if ([appDelegate.tabBarController.selectedViewController respondsToSelector:@selector(topViewController)]) 
    { 
     UINavigationController *nc = (UINavigationController*)appDelegate.tabBarController.selectedViewController; 
     return [nc.topViewController shouldAutorotateToInterfaceOrientation:interfaceOrientation]; 
    } 
    return (interfaceOrientation == UIInterfaceOrientationPortrait); 
} 
0

あなたはアクションを行うことができます。次、schellsan提案の合わせてコードを変更 - appDelegateのプロパティとして(ナビゲーションのViewControllerにプッシュします)currentViewControllerを追加してください。 View Controllerをプッシュしようとすると、その前に現在のView Controllerに設定されます。次へ - ナビゲーションコントローラのrootViewControllerのサブクラスを作成します。あなたは、ナビゲーションバーを使用していない場合は、このサブクラスowerload方法

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { 
    // Overriden to allow any orientation. 
    return [appDelegate.currentViewController shouldAutorotateToInterfaceOrientation:interfaceOrientation]; 
} 

ではそれは働くべきで、すべてのビューコントローラの古い

+3

iOS 6バージョンで同じことをどうやって実現しますか? – Krishnan

1

の向きの変更を強制するプライベートAPIがあります:

FakeRootViewController* fakeRootViewController = [[FakeRootViewController alloc] init];[fakeRootViewController.navigationItem setBackBarButtonItem:backButton]; // Set back button 
// The parent navigation controller is the one containing the view controllers in portrait mode. 
fakeRootViewController.parentNavigationController = parentNavigationController; 

UINavigationController* subNavigationController = // Initialize this the same way you have initialized your parent navigation controller. 

UIViewController* landscapeViewController = // Initialize the landscape view controller 

[subNavigationController setViewControllers: 
    [NSArray arrayWithObjects:fakeRootViewController, 
               landscapeViewController, nil] animated:NO]; 

[_navigationController presentModalViewController:subNavigationController animated:YES]; 

はlandscapeViewControllerもこの実装を持つべきであるということを覚えておいてください。中に入れて、あなたのプッシュView Controllerの-viewWillAppear:

if ([UIDevice instancesRespondToSelector:@selector(setOrientation:)]) { 
    [[UIDevice currentDevice] setOrientation:UIInterfaceOrientationPortrait]; 
} 

コンパイラの警告を抑止するには、あなたのビューコントローラの.mファイルにこれを追加します。

@interface UIDevice() 
- (void)setOrientation:(UIDeviceOrientation)orientation; // private API to let POIEntryVC be pushed over landscape route view 
@end 

いつものように、拒否される危険がありますし、プライベートAPIを使用している場合、将来のOSバージョンで破損する危険性があります。あなた自身の責任で行ってください!

一般に、モーダルビューコントローラを提示する方が、ほとんどの場合、より良い解決策です。

関連する問題