13

xCode 4.2にアップグレードしましたが、これは新しいストーリーボード機能です。ただし、縦向きと横向きの両方をサポートする方法を見つけることができませんでした。

もちろん、私はプログラムでそれを行いました。昔のように、ポートレート用とランドスケープ用の2つのビューを使用しました。

if (interfaceOrientation == UIInterfaceOrientationLandscapeLeft || interfaceOrientation == UIInterfaceOrientationLandscapeRight) 
    {
        self.view = self.landscapeView;
    }
    else
    {
        self.view = self.portraitView;
    }

しかし、私はこれをどうにかして自動的に行う方法を探していました。つまり、今はxCode 4.2ですが、もっと期待していました。皆さんありがとう。

==================================
一時的な解決策:

ここで一時的な解決策を紹介します。私はそれが一時的なものだと言います、なぜなら私はまだAppleの人たちがこれについて本当に賢いことをするのを待っているからです。

「MainStoryboard_iPhone_Landscape」という別の.storyboardファイルを作成し、そこにランドスケープビューコントローラーを実装しました。実際には、通常の(ポートレート).storyboardとまったく同じですが、すべての画面がランドスケープモードになっています。

そこで、横向きのストーリーボードからViewControllerを抽出し、回転が発生したら、self.viewを新しいviewControllerのビューに変更するだけです。

1.向きが変わったときに通知を生成します。

[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];

2.通知を探します:

[[NSNotificationCenter defaultCenter] addObserverForName:UIDeviceOrientationDidChangeNotification object:nil queue:nil usingBlock:^(NSNotification *note) {    
    // We must add a delay here, otherwise we'll swap in the new view  
    // too quickly and we'll get an animation glitch  
    [self performSelector:@selector(updateLandscapeView) withObject:nil afterDelay:0];
}];

3.updateLandscapeViewを実装します

- (void)updateLandscapeView {  
 //>     isShowingLandscapeView is declared in AppDelegate, so you won't need to declare it in each ViewController
 UIDeviceOrientation deviceOrientation       = [UIDevice currentDevice].orientation;
 if (UIDeviceOrientationIsLandscape(deviceOrientation) && !appDelegate().isShowingLandscapeView)
 {
     UIStoryboard *storyboard                = [UIStoryboard storyboardWithName:@"MainStoryboard_iPhone_Landscape" bundle:[NSBundle mainBundle]];
     MDBLogin *loginVC_landscape             =  [storyboard instantiateViewControllerWithIdentifier:@"MDBLogin"];
     appDelegate().isShowingLandscapeView    = YES;  
     [UIView transitionWithView:loginVC_landscape.view duration:0 options:UIViewAnimationOptionTransitionCrossDissolve|UIViewAnimationCurveEaseIn animations:^{
         //>     Setup self.view to be the landscape view
         self.view = loginVC_landscape.view;
     } completion:NULL];
 }
 else if (UIDeviceOrientationIsPortrait(deviceOrientation) && appDelegate().isShowingLandscapeView)
 {
     UIStoryboard *storyboard                = [UIStoryboard storyboardWithName:@"MainStoryboard_iPhone" bundle:[NSBundle mainBundle]];
     MDBLogin *loginVC                       = [storyboard instantiateViewControllerWithIdentifier:@"MDBLogin"];
     appDelegate().isShowingLandscapeView    = NO;
     [UIView transitionWithView:loginVC.view duration:0 options:UIViewAnimationOptionTransitionCrossDissolve|UIViewAnimationCurveEaseIn animations:^{
         //>     Setup self.view to be now the previous portrait view
         self.view = loginVC.view;
     } completion:NULL];
 }}

皆さん、頑張ってください。

PS:Ad Taylorの回答を受け入れます。長い間待って解決策を探した後、彼の回答から着想を得たものを実装することになったからです。テイラーに感謝します。

4

3 に答える 3

6

これは古い質問ですが、私はその日の早い段階でこれを読んだ後、より良い解決策を見つけるためにかなりの時間を費やさなければなりませんでした。私は、AppleAlternativeViewの例をハッキングしてこの解決策を思いついた。基本的には、ランドスケープビューのモーダルビューを提供しています。

#pragma mark Rotation view control

- (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
    [self performSelector:@selector(updateLandscapeView) withObject:nil afterDelay:0];
}

- (void)updateLandscapeView
{
    UIDeviceOrientation deviceOrientation = [UIDevice currentDevice].orientation;
    if (UIDeviceOrientationIsLandscape(deviceOrientation) && !self.isShowingLandscapeView)
    {
        [self performSegueWithIdentifier: @"toLandscape" sender: self];
        self.isShowingLandscapeView = YES;
    }
    else if (deviceOrientation == UIDeviceOrientationPortrait && self.isShowingLandscapeView)
    {
        [self dismissModalViewControllerAnimated:YES];
        self.isShowingLandscapeView = NO;
    }    
}


- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    // Return YES for supported orientations
    return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
于 2012-01-27T18:04:08.013 に答える
3

一般に、方向が大きく異なる場合を除いて、方向ごとに別々のビューを考えるべきではありません(おそらく、そうではないはずです)。代わりに、スーパービューのフレームが変更されたときに、基本的な制限に基づいてビューのコンテンツをできるだけ多くレイアウトするために、自動サイズ変更マスクを使用する必要があります。これにより、サブビューは、多くの場合、インターフェイスの向きの変更の結果として、スーパービューのフレームの変更に適切に応答できるようになります。

あなたの質問にもっと直接的に答えるために、いいえ、Xcodeが特定のインターフェースの向きにどのビューを使用したいかを推測したり教えたりする方法はありません。これはUIKitのビューアーキテクチャの意図ではなかったからです。

自動サイズ変更マスクの詳細については、次のとおりです。自動サイズ変更ルールを使用したレイアウト変更の自動処理

于 2011-10-18T07:04:50.317 に答える
3

XCode v4.2.1では、StoryBoardsを使用する場合、ビューコントローラの方向のみを変更でき、ビュー自体は変更できません。そのため、そこに別のビューを挿入した場合、その方向を変更することはできません。正しく表示します。

したがって、ストーリーボードを使用する場合(ビューの向きを個別のビューに対して変更できるNIBを使用する場合)、2つのビューを持つ以前の方法は機能しないように見えます。

于 2012-01-12T14:45:33.220 に答える