2012-08-02 41 views
1

我到目前为止所做的工作正在工作,但我想知道这是否正确的方式。如何正确地从另一个viewController删除一个引脚

我有一张地图,显示一个注释,当它被按下时显示一个标注。

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

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

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

这是正确的方法吗?

回答

1

而不是直接操作父(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

DetailViewController *dvc = [[DetailViewController alloc] init... 
dvc.annotation = view.annotation; 
dvc.delegate = self; 
[self presentModalViewController:dvc animated:YES]; 

最后,还实现委托方法:

在地图控制器.M,在您创建的详细视图calloutAccessoryControlTapped,设置委托属性,而不是地图视图属性:

-(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可能是有用的。

+0

感谢您的优秀解释。迄今为止,这比我学到的要先进得多。但是,它很了解它。谢谢 – Camus 2012-08-03 15:42:11

+0

还有一个问题Anna,为什么你设置dvc.annotation如果你没有声明它是一个属性。谢谢 – Camus 2012-08-05 08:40:22

+0

我假设你已经在细节控制器上拥有这样一个属性,所以它知道要显示哪个注释。如果没有,你可以添加它。 – Anna 2012-08-05 14:43:07

相关问题