2013-07-01 5 views
6

私はコンテナVCを最近頻繁に使用していましたが、メインVcとコンテナVC間で通信する最良の方法は何か不思議でした。今は通知を使用していますが、私はむしろより良いものを使いたいと思っています。少なくともコンテナVCへのポインタを取得して、委任を使用することはできますか?どんな良い方法?コンテナビューとの通信に関するベストプラクティスは何ですか

+0

コンテナビューと埋め込みセグがあるストーリーボードを使用しているか、ビューコントローラを作成してコードに接続していますか? –

+0

内部が容器であるVc。ストーリーボードの使用 –

答えて

22

コンテナビューコントローラは、prepareForSegue:sender:メソッドで自身と埋め込みビューコントローラとの間に必要な接続を設定する必要があります。

iOSプログラミングでは、View Controller間のこの通信スタイルのパターンがあります。それについては“Coordinating Efforts Between View Controllers” in the *View Controller Programming Guide for iOS”で読むことができます。

しかし、具体的な例を理解することは簡単だと思います。のは、iPhone用のGoogleマップのアプリを使ってみましょう:

Google Maps app for iPhone

私はこのアプリが実装されている正確にどのように知りません。しかし、検索バー(上部)とロケーションバー(下部)を管理するトップレベルのAppViewControllerがあり、コンテナビューにMapViewControllerが埋め込まれているとします。

ビューコントローラ間にはいくつかの相互作用があります。ユーザーが検索すると、AppViewControllerMapViewControllerにいくつかのマップマーカーを配置し、その1つを拡大するように指示する必要があります。ユーザーがマップマーカーをタップすると、MapViewControllerAppViewControllerに、そのマーカーに関する情報を下部のロケーションバーに表示するように指示する必要があります。

パターンは次のとおりです。

@class MapMarker; 
@class MapViewController; 

@protocol MapViewControllerDelegate <NSObject> 

- (void)mapViewController:(MapViewController *)mapViewController didSelectMarker:(MapMarker *)marker; 

@end 

我々はAppViewControllerを行います。まず

は、我々はMapViewController(埋め込みビューコントローラです)(コンテナビューコントローラがある)AppViewControllerに送信されますが、メッセージのためのプロトコルを定義しますこのプロトコルに従う。したがって、MapViewControllerは具体的にAppViewControllerについて知る必要はありません。プロトコルに準拠したオブジェクトへの参照が必要です。また、MapViewControllerは、マーカーを設定するメッセージと、特定のマーカーをズームするメッセージを理解する必要があります。 delegateプロパティが保持サイクルを避けるためにweakであること

@interface MapViewController : UIViewController 

@property (nonatomic, weak) id<MapViewControllerDelegate> delegate; 

- (void)setMarkers:(NSArray *)markers; 
- (void)zoomToMarker:(MapMarker *)marker; 

@end 

注:だから我々はこのようMapViewControllerを宣言します。

AppViewControllerは、MapViewControllerDelegateプロトコルに準拠する必要があります。通常、適合性はAppViewControllerのパブリックインターフェイスの一部である必要はないので、AppViewController.mのクラス拡張の適合性を宣言します。 AppViewControllerにはMapViewControllerへの参照も必要です。

embed segue identifier

は、今、私たちはプロパティを配線するprepareForSegue:sender:メソッドを実装することができます:

@interface AppViewController() <MapViewControllerDelegate> 

@property (nonatomic, strong) MapViewController *mapViewController; 

@end 

次に、我々はストーリーボードに入り、埋め込みセグエを選択し、それに識別子を与える

@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. 
} 

AppViewControllermapviewController:didSelectMarker:とを実装する必要があります10はsetMarkers:zoomToMarker:を実装する必要があります。

+0

うわー、素晴らしい答え! – woobione

関連する問題