iOSプロジェクトでストーリーボードを使用するタイミングとXIBを使用するタイミングに関するガイドラインはありますか?それぞれの長所と短所は何ですか?また、それぞれがどのような状況に適していますか?
私が知る限り、ダイナミックUI要素(マップピンなど)によってビューコントローラーがプッシュされている場合にストーリーボードセグエを使用するのはそれほどクリーンではありません。
iOSプロジェクトでストーリーボードを使用するタイミングとXIBを使用するタイミングに関するガイドラインはありますか?それぞれの長所と短所は何ですか?また、それぞれがどのような状況に適していますか?
私が知る限り、ダイナミックUI要素(マップピンなど)によってビューコントローラーがプッシュされている場合にストーリーボードセグエを使用するのはそれほどクリーンではありません。
2016 年 1 月 12 日更新: 2016 年になりましたが、UI をストーリーボードではなくコードでレイアウトすることを好みます。そうは言っても、ストーリーボードは長い道のりを歩んできました。この投稿から、2016 年には当てはまらないすべてのポイントを削除しました。
更新 2015 年 4 月 24 日: 興味深いことに、 Peter Steinberger が気づいたように("Interface Builder" という小見出しの下で)、Apple は最近オープンソース化された ResearchKit でストーリーボードを使用していません。
2014 年 6 月 10 日更新: 予想どおり、Apple はストーリーボードと Xcode を改善し続けています。iOS 7 以前に適用されたポイントの一部は、iOS 8 には適用されなくなりました (現在はそのようにマークされています)。したがって、ストーリーボードには本質的にまだ欠陥がありますが、使用しないことから、適切な場所で選択的に使用することへのアドバイスを修正します。
iOS 9が出た今でも、私はアドバイスしますに対してストーリーボードを使用するかどうかを決定する際には注意が必要です。ここに私の理由があります:
ストーリーボードはコンパイル時ではなく実行時に失敗します: セグエ名にタイプミスがあるか、ストーリーボードで間違って接続していますか? 実行時に爆発します。ストーリーボードにもう存在しないカスタム UIViewController サブクラスを使用していますか? 実行時に爆発します。コードでそのようなことを行うと、コンパイル時の早い段階でそれらをキャッチできます。更新: 私の新しいツールStoryboardLintは、この問題をほぼ解決します。
ストーリーボードはすぐに混乱します: プロジェクトが大きくなるにつれて、ストーリーボードをナビゲートするのがますます難しくなります。また、複数のView Controllerに他の複数のView Controllerへの複数のセグエがある場合、ストーリーボードがすぐにスパゲッティのボウルのように見え始め、ズームイン、ズームアウト、あちこちスクロールして、探しているView Controllerを見つけます。 for と、どのセグエがどこを指しているかを調べます。更新: この問題は、Pilky によるこの記事と Robert Brown によるこの記事で説明されているように、ストーリーボードを複数のストーリーボードに分割することでほとんど解決できます。
ストーリーボードはチームでの作業を難しくします: 通常、プロジェクトには 1 つの巨大なストーリーボード ファイルしかないため、複数の開発者がその 1 つのファイルを定期的に変更することは頭痛の種になる可能性があります: 変更をマージし、競合を解決する必要があります。競合が発生した場合、それを解決する方法を説明するのは困難です。Xcode はストーリーボード XML ファイルを生成しますが、実際には、編集どころか人間が読み取らなければならないという目標を念頭に置いて設計されていません。
ストーリーボードは、コード レビューを難しくするか、ほとんど不可能にします : ピア コード レビューは、チームで行うのに最適です。ただし、ストーリーボードに変更を加えた場合、これらの変更を別の開発者に確認することはほとんど不可能です。プルアップできるのは、巨大な XML ファイルの diff だけです。実際に何が変わったのか、それらの変更が正しいのか、それとも何かが壊れたのかを解読するのは非常に困難です。
ストーリーボードはコードの再利用を妨げます: 私の iOS プロジェクトでは、通常、アプリ全体で使用するすべての色、フォント、余白、インセットを含むクラスを作成して、一貫したルック アンド フィールを提供します: 必要な場合は 1 行の変更ですアプリ全体でこれらの値を調整します。ストーリーボードでそのような値を設定すると、それらが複製され、それらを変更したいときにすべての出現箇所を見つける必要があります。ストーリーボードには検索と置換がないため、見落とす可能性が高くなります。
ストーリーボードにはコンスタントなコンテキスト スイッチが必要です: ストーリーボードよりもコードの方がはるかに高速に作業およびナビゲートできます。アプリでストーリーボードを使用する場合、常にコンテキストを切り替えます。「ああ、このテーブル ビュー セルをタップして、別のビュー コントローラーをロードしたいのです。ストーリーボードを開いて、適切なビュー コントローラーを見つけ、新しいセグエを作成する必要があります。他のView Controller(これも見つける必要があります)に、セグエに名前を付け、その名前を覚えて(ストーリーボードで定数や変数を使用できません)、コードに戻り、名前を間違えないようにします私の prepareForSegue メソッドのセグエです。ここに 3 行のコードを入力できたらいいのにと思います。」いいえ、楽しくありません。コードとストーリーボード (およびキーボードとマウス) を切り替えると、すぐに古くなり、速度が低下します。
ストーリーボードはリファクタリングが難しい: コードをリファクタリングするときは、ストーリーボードが期待するものと一致していることを確認する必要があります。ストーリーボード内で物事を動かした場合、それがコードで引き続き機能するかどうかは、実行時にのみわかります。2 つの世界を同期させる必要があるかのように感じます。私の謙虚な意見では、それはもろく感じられ、変化を思いとどまらせます。
ストーリーボードは柔軟性に欠けます: コードでは、基本的にやりたいことは何でもできます! ストーリーボードを使用すると、コードで実行できることのサブセットに制限されます。特に、アニメーションやトランジションを使って高度なことをしたい場合、それを機能させるために「ストーリーボードと格闘」していることに気付くでしょう。
ストーリーボードでは、特別なビュー コントローラーのタイプを変更できUITableViewController
ませんUICollectionViewController
。それとも平野にUIViewController
?ストーリーボードではできません。古いView Controllerを削除して新しいView Controllerを作成し、すべてのセグエを再接続する必要があります。このようなコードの変更は、はるかに簡単です。
ストーリーボードは、プロジェクトに 2 つの追加の責任を追加します。(1) ストーリーボード XML を生成するストーリーボード エディター ツールと、(2) XML を解析し、そこから UI およびコントローラー オブジェクトを作成するランタイム コンポーネントです。どちらの部分にも、修正できないバグがある可能性があります。
ストーリーボードでは、サブビューを : に追加することはできませんUIImageView
。理由は誰にもわかりません。
ストーリーボードでは、個々のビュー (-コントローラー) の自動レイアウトを有効にすることはできません: ストーリーボードで [自動レイアウト] オプションをオンまたはオフにすることで、変更がストーリーボードのすべてのコントローラーに適用されます。(この点について Sava Mazăre に感謝します!)
ストーリーボードには、下位互換性が失われるリスクが高くなります。Xcode は、ストーリーボードのファイル形式を変更することがありますが、今日作成したストーリーボード ファイルを数年後、さらには数か月後に開けることを保証するものではありません。(この点については thinkadvances に感謝します。元のコメントを参照してください)
ストーリーボードはコードをより複雑にする可能性があります: コードでビュー コントローラーを作成する場合、カスタムinit
メソッドを作成できますinitWithCustomer:
。そうすればcustomer
、View Controller の内部を不変にし、この View Controller をオブジェクトなしでは作成できないようにすることができcustomer
ます。ストーリーボードを使用している場合、これは不可能です。prepareForSegue:sender:
メソッドが呼び出されるのを待ってからcustomer
、View Controller にプロパティを設定する必要があります。つまり、このプロパティを変更可能にし、View Controller をcustomer
オブジェクトなしで作成できるようにする必要があります。 . 私の経験では、これによりコードが非常に複雑になり、アプリの流れを理解するのが難しくなります。2016 年 9 月 9 日更新: Chris Dzombak は、この問題について素晴らしい記事を書きました。
It's McDonald's : Microsoft について Steve Jobs の言葉で言えば、It's McDonald's (video) !
これらが、私が絵コンテで作業するのが本当に好きではない理由です。これらの理由のいくつかは、XIB にも当てはまります。私が取り組んできた絵コンテベースのプロジェクトでは、節約できたよりもはるかに多くの時間を費やされ、作業は簡単ではなく複雑になりました。
UI とアプリケーション フローをコードで作成すると、何が起こっているのかをより詳細に制御でき、デバッグが容易になり、間違いを早期に発見しやすくなり、変更を他の開発者に説明しやすくなり、 iPhone と iPad をより簡単にサポートできます。
ただし、すべての UIをコードでレイアウトすることは、すべてのプロジェクトに万能のソリューションではないことに同意します。iPad の UI が特定の場所で iPhone の UI と大きく異なる場合、それらの領域だけに XIB を作成するのが理にかなっている場合があります。
上記で概説した問題の多くは Apple によって修正される可能性があり、それが解決されることを願っています。
ちょうど私の2セント。
更新: Xcode 5 では、Apple はストーリーボードなしでプロジェクトを作成するオプションを削除しました。Xcode 4 のテンプレート (Storyboard-opt-out オプションを使用) を Xcode 5 に移植する小さなスクリプトを作成しました: https://github.com/jfahrenkrug/Xcode4templates
私はXIBを広範囲に使用し、ストーリーボードを使用して2つのプロジェクトを完了しました。私の学習は次のとおりです。
ストーリーボードはUI実装の正しい方向への一歩であり、Appleが将来のiOSバージョンでストーリーボードを拡張することを望んでいます。ただし、「単一ファイル」の問題を解決する必要があります。そうしないと、大規模なプロジェクトにとって魅力的ではありません。
小さいサイズのアプリを起動し、iOS5のみの互換性を確保できる場合は、ストーリーボードを使用します。他のすべての場合、私はXIBに固執します。
ストーリーボードは、開発者がアプリケーションとアプリケーションの流れを視覚化するのに役立つように作成されました。これは、たくさんの xib を 1 つのファイルにまとめたものとよく似ています。
これに似た質問があります .xib ファイルと .storyboard の違いは何ですか? .
必要に応じて動的に変更されるコードを介してカスタム遷移を作成することもできます。これは .xibs の場合と同様です。
長所:
短所:
どちらを使用するのが正しいか間違っているかは実際にはありません。それは単に好みの問題であり、使用したい iOS バージョンです。
特に、プロダクト オーナー、プロダクト マネージャー、UX デザイナーなどのチームで作業する必要がある生産的な環境で、ストーリーボードを使用する必要がある4 つの簡単な理由を説明します。
ヨハネスはおそらくすべての実行可能なものを彼の答えにリストしているので、私はCONSを書きません。そして、それらのほとんどは、特に XCode6 の大幅な改善により、実行可能ではありません。
あなたの質問に正しい答えがあるとは思いません。それは個人的な経験の問題であり、あなたがより快適に感じるものです.
私の意見では、ストーリーボードは素晴らしいものです。確かに、実行時にアプリが不可解にクラッシュする理由を見つけるのは非常に困難ですが、しばらくして経験を積むと、それは常にどこかで欠落している IBOutlet に関連していることに気づき、簡単に修正できるようになります。
唯一の本当の問題は、ストーリーボードを使用してバージョン管理されたチームで作業することです.開発の初期段階では、それは本当に混乱する可能性があります. しかし、その最初の段階の後、ストーリーボードを完全に変更する UI の更新は非常にまれであり、ほとんどの場合、xml の最後の部分で競合が発生します。これは、ストーリーボードを再度開いたときに通常は自動修正されるセグエ参照です。 . 私たちのチーム作業では、大量のビュー コードを含む重いビュー コントローラーではなく、これに対処することを好みました。
自動レイアウトに対する多くのコメントを読みました。XCode5 では本当に改善され、レイアウトの自動回転にも非常に適しています。場合によっては、コードで何かを行う必要がありますが、編集する必要がある制約を単純にアウトレットし、その時点でコードで必要なことを行うことができます。それらをアニメーション化することさえできます。
また、ストーリーボードを嫌う人のほとんどは、ある方法から別の方法に移行する方法を (1 つのファイルで) 完全にカスタマイズでき、また (いくつかのトリック) 全体を完全にリロードするのではなく、ビューの内容を更新するだけで、以前にロードされたビュー コントローラーを再利用することさえできます。最後に、コードと同じことを実際に行うことができますが、ストーリーボードとの関係をより適切に分離していると思いますが、多くの点で機能が不足していることに同意します(フォント、色の背景としての画像、ecc ... )。
ストーリーボードのパフォーマンスが気になる場合は、WWDC 2015 セッション 407をご覧ください。
ビルド時間
インターフェイス ビルダーがストーリーボードをコンパイルするとき、最初に 2 つのことを行います。アプリケーションのパフォーマンスを最大化しようとします。次に、作成される nib ファイルの数を最小限に抑えます。
ビューと一連のサブビュー、インターフェースビルダーを備えたビューコントローラーがある場合、ビルド時間はビューコントローラーのnibファイルを作成し、ビューのnibファイルを作成します。
ビューコントローラーとビューの両方に個別のnibファイルを用意することで、ビュー階層をオンデマンドでロードできることを意味します。
実行時間
UI ストーリーボード、API を使用してストーリーボード インスタンスを割り当てる場合、最初にメモリを割り当てるのは UI ストーリーボード インスタンス自体だけです。
ビュー コントローラはありません。ビューはまだありません。
最初のView Controllerをインスタンス化すると、その最初のView Controllerのペン先がロードされますが、誰かが実際に要求するまで、ビュー階層はまだロードされていません。