質問

これは、私にガイダンスを提供してもらうための一般的な質問です。基本的に、私は iPad/iPhone の開発を学んでいて、最終的にマルチオリエンテーションのサポートに関する質問に遭遇しました。

私はかなりの量の doco を調べました。私の本「Beginning iPhone 3 Development」には、それに関する素晴らしい章があります。

しかし、私の質問は、プログラムでコントロールを変更する (または方向ごとに異なるビューを使用する) 場合、一体どうやってコード ベースを維持するのかということです。スパゲッティ コードや何千もの "if" チェックがあちこちにあり、非常に多くの問題が発生することを想像するだけで、UI の配置に 1 つの小さな変更を加えるだけで気が狂ってしまうでしょう。

この問題に対処した経験のある人はいますか?それを制御する良い方法は何ですか?

たくさんのマークに感謝します

役に立ちましたか?

解決

私は私のビューコントローラで2つの簡単な方法でこれを行います。

- (void) willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
    [self adjustViewsForOrientation:toInterfaceOrientation];
}

- (void) adjustViewsForOrientation:(UIInterfaceOrientation)orientation {
    if (orientation == UIInterfaceOrientationLandscapeLeft || orientation == UIInterfaceOrientationLandscapeRight) {
        titleImageView.center = CGPointMake(235.0f, 42.0f);
        subtitleImageView.center = CGPointMake(355.0f, 70.0f);
        ...
    }
    else if (orientation == UIInterfaceOrientationPortrait || orientation == UIInterfaceOrientationPortraitUpsideDown) {
        titleImageView.center = CGPointMake(160.0f, 52.0f);
        subtitleImageView.center = CGPointMake(275.0f, 80.0f);
        ...
    }
}

この清潔を保つためにあなたが簡単に区分することができビューの調整は、/ etc /リロード。単一if-elseの条件内部から呼び出されたメソッドを有する。

他のヒント

それは本当にそれはあなたがレイアウトされているかに依存します。

あなたがAppleの設定アプリケーションを見れば、あなたは彼らが最も行のカスタムセルで、レイアウトのためにテーブルビューを使用していることがわかります。それを使用すると、シンプルなインタフェースは、ちょうどセルの幅を充填することによって、かなり安く回転できるようにすることができます。これさえは、各行のエディットテキスト細胞があるメール、のようなものに適用されます。彼らはテーブルのように見えないようにとテーブルが簡単に、目に見えるボタンやラベルだけで、すべて透明にすることができます。

あなたはすべてのUIViewのautoresizingMaskのうち、走行距離の多くを得ることができます。あなたは柔軟性の高さを持つことができ、1つまたは複数のアイテムを持っている場合は、通常のいずれかの方向で良いに見えるインタフェースのレイアウトを得ることができます。それがどのように見えるかに応じて、時にはあなただけのトップにすべてを固定できます。

すべてのインターフェイス要素が正方形に収まる場合は、

まれに、あなたは場所でそれらを回転させるだけのことができます。

あなたが明示的に向きの変更を処理しなければならない2回があります。場合回転に別の下に横から眺め移動ものです。あなたは常に全幅になりたい場合は、例えば各方向に異なる画像を、持っているときに、他のです。

は、時々これらの両方を回避する方法があります。あなたは、伸縮性の画像を使用するか、1行に1つのビューに自分を制限される場合があります。それとも、特定のビューの向きをロックアウトすることがあります。

は、ビューのレイアウトを変更する必要がある場合は、明示的なlayoutSubviewsの方法があります。あなたは、このいずれかの方法で、すべてのあなたの条件付きレイアウトを処理しようとする必要があります。あなたは、キーボードのための部屋を作っている場合にのみ、ビュー境界が回転に例えば、変更されたときに呼ばれたりしています。回転に応答する必要がある、とは、そこからサブビューをレイアウトすることを各ビュー階層のためのカスタムビューを作成します。

あなたのビューコントローラ:

iPhone SDKは、すべてのあなたのロジック(モデル)があなたのUI(ビュー)から分離しておくのであれば、理論的には、あなたは1箇所のみでUIを心配する必要はありますが、MVCアーキテクチャを持つ中心に構築されています。人のために、あなたはロードするビューコントローラを選択する場合/他そしてちょうど1がロードされるだろう、それぞれがそれぞれの向き、に別々のビューコントローラを持っている可能性があります。

同じアイデアは、あなたがより大きなディスプレイを扱うことができる別のビューコントローラをロードすることができるiPhone / iPadのサポートのために保持します。

私はこのコードを保証することはできませんし、すべて正直にwillRotateToInterfaceOrientation以上素晴らしい作品。ここではiPhone / iPad用のFacebookからFBDialog.mとその上の別テイクです。 (とはいえ、私はこれはWebViewのためだったと思う)。

ここでの要点だ。

[[NSNotificationCenter defaultCenter] addObserver:self
  selector:@selector(deviceOrientationDidChange:)
  name:@"UIDeviceOrientationDidChangeNotification" object:nil];


- (void)deviceOrientationDidChange:(void*)object {
  UIDeviceOrientation orientation = [UIApplication sharedApplication].statusBarOrientation;
  if ([self shouldRotateToOrientation:orientation]) {


    CGFloat duration = [UIApplication sharedApplication].statusBarOrientationAnimationDuration;
    [UIView beginAnimations:nil context:nil];
    [UIView setAnimationDuration:duration];
    [self sizeToFitOrientation:YES];
    [UIView commitAnimations];
  }
}


-(CGAffineTransform)transformForOrientation {
  UIInterfaceOrientation orientation = [UIApplication sharedApplication].statusBarOrientation;
  if (orientation == UIInterfaceOrientationLandscapeLeft) {
    return CGAffineTransformMakeRotation(M_PI*1.5);
  } else if (orientation == UIInterfaceOrientationLandscapeRight) {
    return CGAffineTransformMakeRotation(M_PI/2);
  } else if (orientation == UIInterfaceOrientationPortraitUpsideDown) {
    return CGAffineTransformMakeRotation(-M_PI);
  } else {
    return CGAffineTransformIdentity;
  }
}

- (void)sizeToFitOrientation:(BOOL)transform {
  if (transform) {
    self.transform = CGAffineTransformIdentity;
  }

  CGRect frame = [UIScreen mainScreen].applicationFrame;
  CGPoint center = CGPointMake(
    frame.origin.x + ceil(frame.size.width/2),
    frame.origin.y + ceil(frame.size.height/2));

  CGFloat scale_factor = 1.0f;
  if (FBIsDeviceIPad()) {
    // On the iPad the dialog's dimensions should only be 60% of the screen's
    scale_factor = 0.6f;
  }

  CGFloat width = floor(scale_factor * frame.size.width) - kPadding * 2;
  CGFloat height = floor(scale_factor * frame.size.height) - kPadding * 2;

  _orientation = [UIApplication sharedApplication].statusBarOrientation;
  if (UIInterfaceOrientationIsLandscape(_orientation)) {
    self.frame = CGRectMake(kPadding, kPadding, height, width);
  } else {
    self.frame = CGRectMake(kPadding, kPadding, width, height);
  }
  self.center = center;

  if (transform) {
    self.transform = [self transformForOrientation];
  }
}

あなたの質問には次のように書きました。

スパゲッティ コードや何千もの "if" チェックがあちこちにあり、非常に多くの問題が発生することを想像するだけで、UI の配置に 1 つの小さな変更を加えるだけで気が狂ってしまうでしょう。

これを回避する 1 つの方法は、iPhone/iPad 固有の変更の処理を最初から分割するビュー階層を作成することです。各デバイスにどのビューを最初にロードするかを設定するだけで済みます。次に、通常と同じようにビューコントローラーを作成しますが、作成したビューコントローラーをサブクラス化します。デバイスごとに 1 つのサブクラス。ここに、向きの処理などのデバイス固有のコードを配置できます。このような:

MyViewController.h            // Code that is used on both devices
    MyViewController_iPhone.h // iPhone specific code, like orientation handling
    MyViewController_iPad.h   // iPad specific code, like orientation handling

このアプローチに興味がある場合は、一読をお勧めします この記事. 。とても分かりやすく説明してくれています。

この記事で言及されているものの 1 つは次のとおりです。

--引用開始--

このパターンの利点は、コードに次のようなゴミを散りばめる必要がないことです。

if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
    // The device is an iPad running iPhone 3.2 or later.
    // set up the iPad-specific view
} else {
    // The device is an iPhone or iPod touch.
    // set up the iPhone/iPod Touch view
}

---引用終わり--

それが役立つことを願っています。幸運を!

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top