到目前为止我所做的工作正在进行,但我想知道这是否正确。
我有一个显示注释的地图,按下此按钮会显示标注。
显示的下一个视图是表格视图。该表有一个删除该注释的按钮。
我在类型MKMapView
的表视图中创建了一个属性。在点击callOut附件时初始化此视图后,我设置了MKMapView
属性。
在表格视图中按下按钮时,我会通过map属性删除注释。
这是正确的方法吗?
答案 0 :(得分:1)
而不是直接操作父(地图)控制器视图控件的详细视图,更“正确”的方法可能是使用委托+协议。
使用地图控制器需要实现的方法定义协议(例如deleteAnnotation,detailViewDone等)。
详细视图将具有该协议的委托属性,并通过delegate属性调用协议方法,而不是直接访问和修改其他视图的控件。
地图控制器将自己设置为详细视图的委托,并实际实现协议方法。
这样,每个控制器/类都不必知道其他控件/类的内部细节,让您更容易地改变每个控制器/内部工作的方式,而不会影响其他控制器中的代码(只要协议不更改)。它改善了封装和可重用性。
例如,在详细视图.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也可能有用。