詳細ビューが親(マップ)コントローラービューのコントロールを直接操作するのではなく、より「適切な」アプローチは、デリゲート+プロトコルを使用することです。
マップコントローラーが実装する必要のあるメソッド(例:deleteAnnotation、detailViewDoneなど)を使用してプロトコルを定義します。
詳細ビューには、そのプロトコルのデリゲートプロパティがあり、別のビューのコントロールに直接アクセスして変更する代わりに、デリゲートプロパティを介してプロトコルメソッドを呼び出します。
マップコントローラーは、それ自体を詳細ビューのデリゲートとして設定し、実際にプロトコルメソッドを実装します。
このように、各コントローラー/クラスは、他のコントローラー/クラスがどのように機能するかについての内部の詳細を知る必要がなく、他のコントローラー/クラスのコードに影響を与えることなく、各コントローラー/クラスが内部でどのように機能するかをより簡単に変更できます(プロトコルが変更されない限り)。カプセル化と再利用性が向上します。
たとえば、詳細ビュー.hで、プロトコルを定義し、デリゲートプロパティを宣言します。
@protocol DetailViewControllerDelegate <NSObject>
-(void)deleteAnnotation:(id<MKAnnotation>)annotation;
-(void)detailViewDone;
//could have more methods or change/add parameters as needed
@end
@interface DetailViewController : UIViewController
@property (nonatomic, assign) id<DetailViewControllerDelegate> delegate;
@end
詳細ビュー.mでは、削除ボタンを処理する場所で、代わりにデリゲートメソッドを呼び出します。
if ([delegate respondsToSelector:@selector(deleteAnnotation:)])
{
[delegate deleteAnnotation:annotation];
}
マップコントローラー.hで、プロトコルを実装することを宣言し、メソッドを宣言します。
@interface MapViewController : UIViewController<DetailViewControllerDelegate>
-(void)deleteAnnotation:(id<MKAnnotation>)annotation;
-(void)detailViewDone;
@end
マップコントローラ.mで、詳細ビューを作成するcalloutAccessoryControlTappedで、マップビュープロパティの代わりにデリゲートプロパティを設定します。
DetailViewController *dvc = [[DetailViewController alloc] init...
dvc.annotation = view.annotation;
dvc.delegate = self;
[self presentModalViewController:dvc animated:YES];
最後に、マップコントローラー.mでも、デリゲートメソッドを実装します。
-(void)deleteAnnotation:(id<MKAnnotation>)annotation
{
[mapView removeAnnotation:annotation];
//dismiss the detail view (if that's what you want)...
[self dismissModalViewControllerAnimated:YES];
}
ドキュメントから、「委任とデータソース」および「委任を使用した他のコントローラーとの通信」の記事も役立つ場合があります。