6

私は最近コンテナ VC を頻繁に使用しており、メイン VC とコンテナ VC の間で通信する最良の方法は何かを考えていました。今は通知を使用していますが、もっと良いものを使用したいと思います。少なくとも委任を使用できるように、コンテナー VC へのポインターを取得するにはどうすればよいですか? より良い方法はありますか?

4

1 に答える 1

22

メソッド内で、コンテナ ビュー コントローラと組み込みビュー コントローラとの間に必要な接続を設定するのは、コンテナ ビュー コントローラ次第prepareForSegue:sender:です。

iOS プログラミングでは、ビュー コントローラー間のこのスタイルの通信のパターンがあります。これについては、*View Controller Programming Guide for iOS"</a> の「Coordinating Efforts between View Controllers」を参照してください。

でも、具体例があるとわかりやすいと思います。iPhone 用の Google マップ アプリを使用してみましょう。

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.mAppViewControllerAppViewControllerMapViewController

@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:

于 2013-07-01T05:09:41.780 に答える