2011-10-25 12 views
7

背景&目的:私はUISplitViewControllerベースのiPadアプリを持っています - これまでは4方向をサポートしていましたが、今はランドスケープのみにロックしたいと思います。 左ビューコントローラのshouldAutorotateToInterfaceOrientationを変更して横向きモードのみをサポートしましたが、これによりviewWillAppearが呼び出されなくなりました。ViewWillAppearはUISplitViewControllerで呼び出されません

詳細:私のiPadのビューコントローラは以下のように編成されています。両方DetailViewController.mHostManagerViewController.m

が含まれている場合

- (BOOL)application:(UIApplication *)application 
     didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 
    HostManagerViewController *hvc = [[[HostManagerViewController alloc] 
             initWithNibName:nil bundle:nil] autorelease]; 
    self.detailViewController = [[[DetailViewController alloc] 
           initWithNibName:nil bundle:nil] autorelease]; 
    UINavigationController *rootNav = [[[UINavigationController alloc] 
             initWithRootViewController:hvc] autorelease]; 
    UISplitViewController *splitVC= [[[UISplitViewController alloc] init] autorelease]; 
    [splitVC setViewControllers:[NSArray arrayWithObjects:rootNav, 
           detailViewController, nil]]; 

    splitVC.delegate = detailViewController; 
    [window addSubview:splitVC.view]; 
    [window setRootViewController:splitVC]; 
    return YES; 
} 

viewWillAppearが呼び出されます:

window 
`-- splitVC (UISplitViewController) 
    `-- rootNav (UINavigationController) 
     `-- hvc (HostManagerViewController, derived from UIViewController) 
    `-- detailViewController (DetailViewController, derived from UIViewController) 

これは以下のようにアプリケーションデリゲートで実装されています

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { 
    return YES; 
} 
Console output: 
Should rotate called to hostmanager with 1 
Should rotate called to hostmanager with 1 
Should rotate called to hostmanager with 1 
Should rotate called to hostmanager with 3 
Hostmanager: Viewdidload 
Should rotate called to hostmanager with 1 
Hostmanager: viewwillappear 

私は「を

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

へのコード」HostManagerViewControllerを変更したときしかしHostManagerViewControllerのviewWillAppear`が呼び出されていません。コンソール出力は

Should rotate called to hostmanager with 1 (1 is the numeric value of interfaceOrientation) 
Should rotate called to hostmanager with 1 
Should rotate called to hostmanager with 1 
Should rotate called to hostmanager with 1 
Should rotate called to hostmanager with 3 
Should rotate called to hostmanager with 3 
Should rotate called to hostmanager with 1 
Should rotate called to hostmanager with 1 
Should rotate called to hostmanager with 1 
Should rotate called to hostmanager with 3 
Should rotate called to hostmanager with 1 
Should rotate called to hostmanager with 1 
Should rotate called to hostmanager with 1 
Should rotate called to hostmanager with 3 
Should rotate called to hostmanager with 1 
Should rotate called to hostmanager with 1 
Should rotate called to hostmanager with 1 
Should rotate called to hostmanager with 3 
Hostmanager: Viewdidload 
Should rotate called to hostmanager with 1 

のみランドスケープモードは、Info.plistの

EDITでサポートされています:挿入のNSLogメッセージは基本的にshouldAutorotateToInterfaceOrientationviewWillAppearViewDidLoad

+0

このプロジェクトのサンプルをアップロードすることは可能ですか? – ACBurk

+0

これを実行しているiOSバージョンは何ですか? – ACBurk

+0

私は4.3を使用しています。それをより小さなテストケースに縮小することができます。どこにアップロードしますか? –

答えて

8

:YESとDetailViewControllerに私が追加することになりオールウェイズ返すためにHostManagerViewControllerにshouldAutorotateToInterfaceOrientation - 私が変わってしまいます動作は4.3と5.0の間で異なります。実際には5.0ですべての正しい呼び出しを行います。私はこれを単にUISplitviewControllerのバグと信じています。 Splitviewのコントローラはかなりバグだった。 aopsfanの答えは問題を解決しません(私はこれを確認しました)。私は、サブクラス化uisplitviewcontrollerを提案し、splitviewコントローラのviewwillappearをオーバーライドするので、同じようviewdidappearます:

#import "testSplitViewController.h" 

@implementation testSplitViewController 

-(void)viewWillAppear:(BOOL)animated { 
    [super viewWillAppear:animated]; 

    NSString *reqSysVer = @"5.0"; 
    NSString *currSysVer = [[UIDevice currentDevice] systemVersion]; 
    if ([currSysVer compare:reqSysVer options:NSNumericSearch] == NSOrderedAscending) 
     [[[self viewControllers] objectAtIndex:0] viewWillAppear:animated]; 
} 

-(void)viewDidAppear:(BOOL)animated { 
    [super viewDidAppear:animated]; 

    NSString *reqSysVer = @"5.0"; 
    NSString *currSysVer = [[UIDevice currentDevice] systemVersion]; 
    if ([currSysVer compare:reqSysVer options:NSNumericSearch] == NSOrderedAscending) 
     [[[self viewControllers] objectAtIndex:0] viewDidAppear:animated]; 
} 
@end 

あなたは二回viewDidAppearコールをしないように、バージョン番号を確認する必要があります。

可能であれば、バグが修正されている可能性があるため、またはできるだけ上に移動してください。

+0

はい、はいとはい!分割ビューコントローラにはバグがあるようです - 分割ビューからの子ビューの 'viewWillAppear'を強制的に回避するように思われます。ありがとう、@ACBurk –

+0

'viewDidAppear'を呼び出す前にバージョンチェックよりも一般的な方法がありますか? 'isViewLoaded'がありますが、' hasViewAppeared'コールもありますか? –

+0

私は頭の上から知りませんが、私はそれを調べます – ACBurk

3

を追跡するために、UISplitViewControllerは2つの部分を持っているので、あなたが必要shouldAutorotateの普遍的な実装です。私はあなたのviewWillAppearの問題を再現することができなかったことに注意してください。しかし、このソリューションは本当に推測です。

デッドシンプルサブクラスUISplitViewControllerを作成することをお勧めします。 "SplitViewController" という名前を付け、それに.mファイルですが、このようになりますshouldAutorotate以外のすべて、削除:今すぐ

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

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

を今すぐ裏にHostManagerViewControllerDetailViewControllerであなたのshouldAutorotateコードを変更、あなたのアプリケーションデリゲートでは、UISplitViewControllerの代わりにこのクラスを使用してください。これにより、問題が解決されるはずです。

+0

私もaopsfanに同意します。これは各View Controllerでこれをブロックするべきではありません。ルートコントローラ(あなたの場合はUISplitViewController)でブロックする必要があります。 – alinoz

+0

+1これを提案していただきありがとうございます。残念ながら、それは問題を解決しませんでした –

0

あなたは、私がDetailViewControllerではなくHostManagerViewControllerになります回転を阻止するのに最適な場所だと思いdetailViewController

splitVC.delegate = detailViewController; 

にUISplitViewControlerのデリゲートを設定します。私は私があなたの問題の簡単な再現を作成しようとしましたので、あなたが使用していた何のiOSバージョン尋ねた

-(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation 
{ 
    return (UIInterfaceOrientationIsLandscape == interfaceOrientation); 
} 
関連する問題