web-dev-qa-db-ja.com

一度に複数のViewControllerが画面に表示されますか?

CocoaTouchのコントローラーに頭を包み込もうとしています。主な問題は、一度に複数のコントローラーを「画面上」に配置したいということです。自分のコントローラー(たとえばB)によって制御される小さなビューで構成される大きなビュー(コントローラーAを使用)が必要です。分割するとコードがずっときれいになるので、このようにしたいです。悪い点は、追加のコントローラー(タイプB)が画面上の「一級市民」ではないことです。たとえば、自動ローテーションのクエリや通知を受信しません。 (モーダルコントローラーを簡単に表示することはできません。親コントローラーにpresentModal…メッセージを送信する必要があります。)

Cocoaの観点から見たAコントローラーとBコントローラーの違いは何ですか?システムは、通知などを送信する特権コントローラーである「最前線のコントローラー」へのある種のポインターを保持していますか?ビューが画面に表示されているのに、他のコントローラーがそれらを受け取らないのはなぜですか?複数のコントローラーを「画面上」に置くことはハックと見なされますか?それともサポートされていて、私はいくつかのポイントを逃していますか?ありがとうございました。


私が解決しようとしている問題の詳細:私は簡単な写真ブラウザを書いています。写真は全画面表示され、ユーザーは左または右にスワイプして写真を変更できます。 Aコントローラーがスクロール部分を処理し、Bコントローラーが各写真自体を処理します。

写真はネットワークから読み込まれ、ネットワークがダウンしているなど、発生する可能性のあることがたくさんあるため、Bを分離することは良い考えのように思われました。 Bコントローラーでは、Bは1つの特定の写真でのみ機能するため、コードはかなり単純です。コードをAコントローラーに移動すると、問題が発生します。

現在のソリューションで気に入らないのは、「ファーストクラス」のコントローラーではないBを手動で回避する必要があることだけです。いくつかの呼び出しをAからBに手動で渡す必要があり、Bがモーダルダイアログを表示したい場合は、presentModal…をAに送信する必要があります。これは醜いです。

20
zoul

IOS 5以降、このシナリオはファーストクラスでサポートされています。これはコントローラーの封じ込めと呼ばれます。

Swiftコントローラーの封じ込め

objcコントローラーの封じ込め

14
zoul

元の質問とは密接に関連していませんが、重要です。 Appleは、View Controllerプログラミングガイドで、ViewControllerが1つの画面のコンテンツを正確に制御する責任があることを明確に述べています。

「作成する各カスタムViewControllerオブジェクトは、1画面分のコンテンツを正確に管理する責任があります。ViewControllerと画面間の1対1の対応は、アプリケーションの設計において非常に重要な考慮事項です。複数を使用しないでください。同じ画面のさまざまな部分を管理するためのカスタムViewController。同様に、単一のカスタムViewControllerオブジェクトを使用して複数の画面に相当するコンテンツを管理しないでください。

注:1つの画面を複数の領域に分割し、それぞれを個別に管理する場合は、View Controllerオブジェクトの代わりに汎用コントローラーオブジェクト(NSObjectから派生したカスタムオブジェクト)を使用して、画面の各サブセクションを管理します。次に、単一のビューコントローラオブジェクトを使用して、汎用コントローラオブジェクトを管理します。ビューコントローラは、画面全体の相互作用を調整しますが、必要に応じて、管理する汎用コントローラオブジェクトにメッセージを転送します。」

ただし、iPadプログラミングガイドでは、コンテナビューコントローラが存在する可能性があるとも述べています。

「ビューコントローラーは単一のビューを担当します。ほとんどの場合、ビューコントローラーのビューはアプリケーションウィンドウのスパン全体を占めると予想されます。ただし、場合によっては、ビューコントローラーが別のビューコントローラー(既知)内に埋め込まれていることもあります。コンテナビューコントローラとして)、他のコンテンツと一緒に表示されます。ナビゲーションおよびタブバーコントローラは、コンテナビューコントローラの例です。」

私の現在の知識までは、ビューコントローラーでサブビューコントローラーを使用しませんでしたが、NSObjectをサブクラス化して、メインビューコントローラーからメッセージを送信しようとしました。

このスレッドもチェックしてください: MGSplitViewControllerディスカッション

12
Peter Z.

まず、これは重要です。ビューコントローラーが「画面上」に表示されない-ビューします。 「トップレベル」のコントローラーは、説明している種類のメッセージを「サブビューコントローラー」に確実に渡すことができます。実際、これがほとんどのアプリの動作方法です。タブバーがあり、ビューがナビゲーションコントローラーを使用するアプリについて考えてみます。実際には、複数のビューコントローラが同時に「実行」されており、それぞれが同時に画面上に独自のビューを持っています。「ルート」ビューコントローラはUITabBarControllerのインスタンス(またはサブクラス)になり、それぞれに複数のネストされたUINavigationControllerがあります。ネストされたビューコントローラ(UITableViewControllerのインスタンスやサブクラスなど)を表示します。

レスポンダーチェーン がどのように機能するかについて少し読んでおくとよいでしょう。タッチイベントについて考えてみましょう。スタックの最上位に最も近いビューに対して生成され、イベントを受信できます。これもタップの下にあります。そのビューがそれを処理できない場合、何かがそれを処理するまで(そしてそれを食べるまで)、ビュー階層の食物連鎖を通過します。

あなたの質問の詳細に関しては、全体として、あなたが説明する戦略が複雑さの点であなたに利益をもたらすために実際に何をしているのか正確にはわかりません。実装の正確さにもよりますが、小さなサブビューごとに個別のView Controllerを使用すると、すべてのサブビューコンポーネントを認識している1つのViewControllerを使用するよりも多くのブックキーピングコードが必要になる場合があります。

8
Shaggy Frog

これはかなり古い質問ですが、今日同じ問題に直面する可能性のある人々がいると思うので、私の解決策を共有したいと思います。私は、多くの情報、ページ付け、コントロールなどを備えたこの1つの画面を持つこのアプリケーションを作成していました。AppleのMVCによると documentation ViewControllersの役割については、ビュー自体にロジックを実装しないでください。または、そこから直接データモデルにアクセスするには、数千行のコードを含むMassive ViewControllerを使用するか、(単体テストを使用しても)保守とデバッグの両方が困難であるか、新しい方法を見つけるかを選択する必要がありました。

私の解決策は、以下のようにUIContainerViewを使用することでした: enter image description here

このようにして、各パーツのロジックを独自のViewControllerに実装でき、親のViewControllerがビューの制約とサイズ設定を処理します。

注:この回答は方法を示すための単なるガイドであり、その仕組みと実装方法に関する適切で詳細な説明を見つけることができます [〜#〜] here [〜#〜]

6

実際、私たちのほとんどは4.xと5.xを同時にターゲットにしているので、iOS5よりも早く動作させることができます。私は両方で機能するソリューションを作成しました、そしてそれはうまく機能します、appstoreのいくつかのアプリはそれを使用します:)読む これに関する私の記事 または単に ダウンロードして簡単なクラスを使用する =この目的のために作成したもの。

5