15

今日、多方向 iPad アプリを設計する正しい方法は何ですか? 多くの Apple ドキュメント、Web リソース、SO Q&A を読みました。ここに私の最初の要件があります:

  • これは、iOS 5 以降で動作する必要があります。以前のバージョンの iOS との後方互換性を作成する必要はありません。
  • 可能であれば、ポートレートとランドスケープの UI を異なる NIB ファイルで定義したいと考えています。
  • 私のNIBファイルには、同じUI要素に対して異なる向きの異なる画像があります(たとえば、UIImageView header.png.header-landscape.png
  • アプリには複数の画面があり、それぞれの画面の向きを切り替えることができる必要があります。

それで、私は何をしますか?

  • willRotate画面ごとに 1 つの VC を作成し、ハンドラーの基になるビューを置き換えますか?
  • オリエンテーションごとに 1 つの VC を作成しますか? しかし、どうすればそれらを適切に切り替えることができますか?
  • 画像をリロードする必要があるため、単に要素を再配置するだけではうまくいきません (私はそう思います)。
  • すべてをコードで記述しますか (この考えは本当に嫌いです)?

今日の時点で、この問題に対する適切なアプローチは何ですか?

4

5 に答える 5

18

実際には、ほとんどのアーキテクチャの問題と同様に、これは非常に複雑な問題だと思います。1 つの手法だけで問題を解決しようとするべきではないと思います。

このページの他のすべての回答を締めくくらないために、ブログに完全な記事いくつかのサンプル コードへのリンクも投稿しました。

概要

UI は .xib ファイルで表現することをお勧めしますが、今後アプリを変更する人のスキル セットに応じて、これからどの程度逸脱できるかが決まります。プログラマーだけじゃないかも!

優先オプション

1 つの .xib ファイルと 1 つのサブクラスで 1 つの論理ビューを実装することを強くお勧めします。UIViewControllerそれをするために本当に一生懸命努力してください。autoresizesSubviews=YESXIB の rootを設定しview、子ビューを適切に調整してautoresizingMask、画面のサイズ/向きの変更に合わせて調整すると、大いに役立ちます。

しかし、それだけでは十分ではありません。 レイアウトを横向きに調整する必要があり、自動サイズ変更が処理できる範囲を超えている場合は、2 つの主なオプションを使用します。どちらを選択するかは、ビューのコンテンツによって異なります。

オプション 1

縦向きと横向きのレイアウトがあまり変わらない場合は、1 つの .xib のままにし、View Controller に少しのコードを入れて、回転時にレイアウトを調整することをお勧めします。

オプション 2

横向きと縦向きの違いが非常に大きい場合は、向きごとに 1 つの .xib を用意することをお勧めします ( と のような厳密な命名規則に従いMyViewController.xibますMyViewController-landscape.xib)。ただし、両方の .xib ファイルは、File's Owner同じ View Controllerクラスに接続する必要があります。私にとって、これが鍵です。

推奨される代替手段以外のことを行う場合は、再利用可能なUIViewController基本クラスを作成してこれを自動化し、一貫性を保つことをお勧めします。これは、最初に考えるよりも多くの作業であり、UIViewControllerローテーション処理が必要なすべてのサブクラスでこれを続けるのはばかげています。


解決

このような基本クラスを作成し、サンプル プロジェクトに入れました。 3 つのシナリオすべてを処理する必要があると私が考える方法の Hello World の例を確認できます。

  • 1 つのビュー コントローラーと 1 つの .xib、自動サイズ変更のみ ( my FirstViewController)
  • 1 つのビュー コントローラーと 2 つの .xibs、それらの間の自動切り替え (my SecondViewController)
  • 1 つのビュー コントローラーと 1 つの .xib、ローテーションに関するマイナーなプログラム レイアウト ( ThirdViewController)

私が使用するRotatingViewController基本クラスは、iPhone アプリにも同様に適用できます。私は実際には、iPadとiPhone、縦向き横向きのレイアウト (ユニバーサル アプリ用) の維持を処理する、より複雑なバージョンを持っています。

しかし、この質問は iPad に関するものだけだったので、わかりやすくするために簡略化しました。

私の基本クラスimageNamed:には、現在の向きに適した画像をロードするのに役立つユーティリティ メソッドもあります ( image-landscape.png規則で命名されています)。ただし、ほとんどの場合、代わりに伸縮可能な UIImage を使用する必要があると思います。

私はこれをしませんでしたが、デバイスの向きが変わったときに、ツリーをたどってまたはオブジェクトのプロパティを更新RotatingViewControllerしようとすることもできました。私はそこまで行きませんでしたが、あなたならできます。subviewsimageUIButtonUIImageView

これらの推奨事項の根拠については、私が参照しているブログ投稿を参照してください

于 2012-07-27T09:08:34.327 に答える
4

したがって、この質問に対する答えがなく、時間が問題であるため、私は次のことを行うことになりました。

  • Interface Builderを使用して、縦向きのすべての画面のNIBファイルを作成しました。いくつかのレイアウトを必要とするすべてのコントロールをアウトレットにバインドしました。
  • IBを使用して横向きのNIBファイルも作成しましたが、UI要素のフレームが横向きになる場所を確認するための参照にのみ使用しました。
  • すべての要素を横向きに再配置し、willAutoRotateハンドラーで縦向きに戻すコードを追加しました。

この方法により、IBでUIの大部分をリストで作成できる柔軟性が得られました。要素をさまざまな方向に再配置するためのコードを保持する必要がありますが、通常、これsetFrameにはラベル、ボタンなど、およびimageNamed画像のメソッドのみが含まれます。これは、コードですべてのUIを直接作成するよりもはるかに小さいスコープです。

この質問は、iPad / iPhone用のユニバーサルでマルチオリエンテーションのアプリを作成する開発者にとって非常に重要で役立つと思うので、SOが許す限りすぐにこの質問に報奨金を開きます。

于 2012-07-25T00:42:58.037 に答える
2

私は3つの異なる手法を使用しましたが、そのうちの1つは、複数の方向を処理するための「正しい」方法だと思います。

  1. 間違った例:2つの異なるペン先/ペン先を作成しました。「悪い」わけではありませんが、UIViewControllerでUIViewを絶えず再構築しているときに、コンテキストと状態を処理するのは面倒です。
  2. 間違った例:1つのペン先を使用し、絶対座標に基づく回転でそれらを再配置しました。これは間違った方法です。私はこれを何度も見てきましたが、複数の表示モードの処理を達成できる最悪の方法です。この症状は、デバイスの向きを認識するUIViewです。完全に不要。
  3. 正しい例:ビュー内の要素のautoresizingMaskを使用して、デバイスの回転時に要素を適切な位置にフロートさせ、CGRectフレームを使用してその方法で実行できないものを微調整します。私は何かを揃えるためにこれを一度だけ行う必要がありました。私見これは、複数のデバイスの向きを処理する「正しい」方法です。UIViewとサブビューは、回転について知る必要はありません。画面ごとに1つのVCを使用して、多くのサブビューを表示し、シンプルに保つことができます。フローティング要素を使用してこのようにレイアウトを考案できる場合は、黄金色であり、UIは簡単です。

ちょうど私の2セント。

編集:iOS 6ではAutoLayoutが導入され、「支柱とバネ」の代わりに使用できます-https: //developer.apple.com/library/ios/documentation/userexperience/conceptual/AutolayoutPG/Introduction/Introduction.html

于 2012-07-26T17:07:38.570 に答える
0

Apple が、特定のビュー コントローラに対して複数の XIB ファイル (向きごとに 1 つ) を使用する方法を提供していないことは残念です。非常に単純なインターフェースで動作します)。

代わりにこれを行うことができます: 縦向きの XIB を作成し、XIB 内の各サブビューに一意のタグ プロパティを割り当てます。次に、XIB を複製し、横向きのレイアウトをやり直します (これで、縦向きと横向きの 2 つの XIB が作成されます)。

アプリの起動時に、起動方向に適した XIB から最初に View Controller を作成します。すべてのサブビューを再帰的に繰り返し、すべてのサブビュー フレームを含むディクショナリを作成し、各サブビューのタグ プロパティをキーにします。

次に、他の方向の XIB から一時的なビュー コントローラーを作成し、同じ再帰的反復を実行して、タグによってキー設定されたすべてのフレームを 2 番目のディクショナリに格納します (各ディクショナリは方向の 1 つに一致し、それに応じて名前を付ける必要があります)。次に、この 2 番目の一時的なビュー コントローラーを破棄します。

ではlayoutSubviews(実際にはviewDidLayoutSubviews、View Controller を扱っており、iOS 5 以降で実行できるため)、すべてのサブビューを再帰的に反復し、各サブビューに適切なフレームのディクショナリからフレームを割り当てるだけです。サブビューのタグ プロパティに基づく現在の向き。

この手法を使用すると、向きが変わるたびにビュー コントローラーを再読み込みしなくても、ビュー コントローラーの状態を保持できます。また、IB を使用してビュー コントローラーをレイアウトできるため、手動でレイアウト コードを大量に記述する必要がありません。

于 2012-07-31T21:48:32.633 に答える
-3

あらゆることを実行できるアプリケーションを実行する必要はありません。アプリケーションを設計するときは、最適な向き (横向きか縦向きか) を決定します。アプリのデザインで逆向き (すべてが横向きで 1 ~ 2 個のコントローラーが縦向き、またはその逆) が必要な場合でも、それに応じてニブを作成します。場合によっては、すべての向きをサポートするためにコントローラーが必要になります。

しかし、すべてのコントローラーがすべての向きをサポートするようにしようとしています... うーん、この考えは少し奇妙だと思います。

それでもやりたい場合に備えて、可能な解決策をすでにリストしてあります。私は最後のオプションが気に入っています。

于 2012-07-23T23:29:53.043 に答える