如何从另一个viewController中正确删除一个引脚

时间:2012-08-02 12:18:27

标签: objective-c ios uitableview uiviewcontroller mkannotation

到目前为止我所做的工作正在进行,但我想知道这是否正确。

我有一个显示注释的地图,按下此按钮会显示标注。

显示的下一个视图是表格视图。该表有一个删除该注释的按钮。

我在类型MKMapView的表视图中创建了一个属性。在点击callOut附件时初始化此视图后,我设置了MKMapView属性。

在表格视图中按下按钮时,我会通过map属性删除注释。

这是正确的方法吗?

1 个答案:

答案 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 SourcesUsing Delegation to Communicate with Other Controllers也可能有用。