私は最近コンテナ VC を頻繁に使用しており、メイン VC とコンテナ VC の間で通信する最良の方法は何かを考えていました。今は通知を使用していますが、もっと良いものを使用したいと思います。少なくとも委任を使用できるように、コンテナー VC へのポインターを取得するにはどうすればよいですか? より良い方法はありますか?
1 に答える
メソッド内で、コンテナ ビュー コントローラと組み込みビュー コントローラとの間に必要な接続を設定するのは、コンテナ ビュー コントローラ次第prepareForSegue:sender:
です。
iOS プログラミングでは、ビュー コントローラー間のこのスタイルの通信のパターンがあります。これについては、*View Controller Programming Guide for iOS"</a> の「Coordinating Efforts between View Controllers」を参照してください。
でも、具体例があるとわかりやすいと思います。iPhone 用の Google マップ アプリを使用してみましょう。
このアプリがどのように実装されているか正確にはわかりません。しかしAppViewController
、検索バー (上部) とロケーション バー (下部) を管理するトップレベルがありMapViewController
、コンテナ ビューに を埋め込んでいるとします。
ビューコントローラー間にはいくつかの相互作用があります。ユーザーが検索するとき、 はにいくつかのマップ マーカーを配置し、そのうちの 1 つを拡大するAppViewController
ように指示する必要があります。MapViewController
ユーザーがマップ マーカーをタップすると、 は、そのマーカーに関する情報を下部のロケーション バーに表示MapViewController
するように に指示する必要があります。AppViewController
というわけでパターンはこちら。
MapViewController
最初に、 (埋め込みビュー コントローラ) がAppViewController
(コンテナ ビュー コントローラ)に送信するメッセージのプロトコルを定義します。
@class MapMarker;
@class MapViewController;
@protocol MapViewControllerDelegate <NSObject>
- (void)mapViewController:(MapViewController *)mapViewController didSelectMarker:(MapMarker *)marker;
@end
AppViewController
このプロトコルに準拠させます。したがって、は具体的MapViewController
に について知る必要はありませんAppViewController
。プロトコルに準拠するオブジェクトへの参照が必要なだけです。はMapViewController
、マーカーを設定するメッセージと、特定のマーカーにズームするメッセージも理解する必要があります。したがって、次MapViewController
のように宣言します。
@interface MapViewController : UIViewController
@property (nonatomic, weak) id<MapViewControllerDelegate> delegate;
- (void)setMarkers:(NSArray *)markers;
- (void)zoomToMarker:(MapMarker *)marker;
@end
このdelegate
プロパティはweak
保持サイクルを回避するためのものであることに注意してください。
プロトコルAppViewController
に準拠する必要があります。通常、準拠はのパブリック インターフェイスの一部である必要がないため、MapViewControllerDelegate
のクラス拡張でその準拠を宣言します。にも への参照が必要です。AppViewController.m
AppViewController
AppViewController
MapViewController
@interface AppViewController () <MapViewControllerDelegate>
@property (nonatomic, strong) MapViewController *mapViewController;
@end
次に、ストーリーボードに移動し、埋め込みセグエを選択して、識別子を付けます。
prepareForSegue:sender:
これで、プロパティを接続するメソッドを実装できます。
@implementation AppViewController
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:@"MapEmbedding"]) {
[self prepareForMapEmbeddingSegue:segue sender:sender];
}
}
- (void)prepareForMapEmbeddingSegue:(UIStoryboardSegue *)segue sender:(id)sender {
self.mapViewController = segue.destinationViewController;
self.mapViewController.delegate = self;
// We can do any additional setup on mapViewController here,
// like set its initial viewport.
}
AppViewController
も実装する必要がありmapviewController:didSelectMarker:
、 およびMapViewController
を実装する必要があることに注意してください。setMarkers:
zoomToMarker: