与其直接操作父(地图)控制器视图的控件的详细视图相比,更“正确”的方法可能是使用委托+协议。
使用地图控制器需要实现的方法定义协议(例如,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];
}
从文档中,文章Delegates and Data Sources 和Using Delegation to Communicate with Other Controllers 也可能有用。