到目前为止我所做的是工作,但我想知道这是否是正确的方法。
我有一个显示注释的地图,当按下它时显示一个标注。
显示的下一个视图是表格视图。该表有一个用于删除该注释的按钮。
我在类型的表视图中创建了一个属性MKMapView
。在点击 callOut 附件时初始化此视图后,我设置了MKMapView
属性。
在表格视图中按下按钮时,我通过 map 属性删除注释。
这是正确的方法吗?
到目前为止我所做的是工作,但我想知道这是否是正确的方法。
我有一个显示注释的地图,当按下它时显示一个标注。
显示的下一个视图是表格视图。该表有一个用于删除该注释的按钮。
我在类型的表视图中创建了一个属性MKMapView
。在点击 callOut 附件时初始化此视图后,我设置了MKMapView
属性。
在表格视图中按下按钮时,我通过 map 属性删除注释。
这是正确的方法吗?
而不是直接操作父(地图)控制器视图的控件的详细视图,更“正确”的方法可能是使用委托+协议。
使用地图控制器需要实现的方法定义协议(例如 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];
}
从文档中,委托和数据源以及使用委托与其他控制器进行通信的文章也可能很有用。