这是一个注释视图重用问题。
在里面
viewForAnnotation
,按钮目标仅在创建视图时设置(如果
dequeueReusableAnnotationViewWithIdentifier
回报
nil
).
但如果
dequeueReusableAnnotationViewWithIdentifier
返回以前使用过的视图,按钮目标仍然是为之前使用视图的注释设置的。
先前的注释可能与当前注释不同。
因此,注释“two”可以重新使用最初为注释“one”创建的视图,点击已经创建的按钮可以显示“one”而不是“two”的信息。
要解决这个问题,需要做两件事:
-
如果
dequeueReusableAnnotationViewWithIdentifier
返回视图(如果
pinView
不是
无
),代码
必须
更新视图的
annotation
属性设置为当前批注。
-
无论是创建新视图还是重新使用已退出队列的视图,都必须设置按钮目标。最简单的方法是将按钮创建/设置移动到
if
就在
return
.
更新的
注释视图
将如下所示:
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)myAnn {
if ([myAnn isKindOfClass:[MKUserLocation class]])
{
((MKUserLocation *)myAnn).title = @"Your position";
return nil;
}
MKPinAnnotationView *pinView = (MKPinAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:@"pinView"];
if (!pinView) {
pinView = [[MKPinAnnotationView alloc] initWithAnnotation:myAnn reuseIdentifier:@"pinView"];
pinView.pinColor = MKPinAnnotationColorRed;
pinView.canShowCallout = YES;
}
else
{
//1. Re-using a view, update which annotation it's being used for now
pinView.annotation = myAnn;
}
//2. Now pinView is either a new view or re-used view.
//Set its button target based on current annotation...
UIButton *rightButton = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
if ([[myAnn title] isEqualToString:@"Name of the place"]){
[rightButton addTarget:self action:@selector(myAnnClicked:)forControlEvents:UIControlEventTouchUpInside];
}
if ([[myAnn title] isEqualToString:@"Name of place two"]){
[rightButton addTarget:self action:@selector(myAnn2Clicked:)forControlEvents:UIControlEventTouchUpInside];
}
pinView.rightCalloutAccessoryView = rightButton;
return pinView;
}
顺便说一句,不要为每个注释创建单独的方法(这可能会很乏味),而是使用地图视图的
calloutAccessoryControlTapped
委托方法。
事实上,现在,map视图正在调用自定义方法和
Callout AccessoryControl抽头
委托方法(其中当前没有代码)。
在委托方法中,可以通过
view.annotation
.
所以在
注释视图
,您可以这样做:
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)myAnn {
if ([myAnn isKindOfClass:[MKUserLocation class]])
{
((MKUserLocation *)myAnn).title = @"Your position";
return nil;
}
MKPinAnnotationView *pinView = (MKPinAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:@"pinView"];
if (!pinView) {
pinView = [[MKPinAnnotationView alloc] initWithAnnotation:myAnn reuseIdentifier:@"pinView"];
pinView.pinColor = MKPinAnnotationColorRed;
pinView.canShowCallout = YES;
pinView.rightCalloutAccessoryView = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
}
else
{
pinView.annotation = myAnn;
}
return pinView;
}
然后在
Callout AccessoryControl抽头
委托方法,可以执行以下操作:
- (void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view calloutAccessoryControlTapped:(UIControl *)control{
if ([view.annotation isKindOfClass:[Annotation class]])
{
Annotation *myAnn = (Annotation *)view.annotation;
id vcToPush = nil;
if ([[myAnn title] isEqualToString:@"Name of the place"]) {
vcToPush = [[InfoViewController alloc]init];
}
else if ([[myAnn title] isEqualToString:@"Name of place two"]) {
vcToPush = [[InfoTwoController alloc]init];
}
[self.navigationController pushViewController:vcToPush animated:YES];
}
}
然后拆下
myAnnClicked
和
myAnn2Clicked
方法。
您还可以为每个注释创建一个通用的“Info”视图控制器,而不是单独的视图控制器。
其他一些无关的事情:
-
不要在
#define
线
-
您已定义
PLACE2_LONGITUDE
两次
-
newRegion.center
正在使用
地点2_经度
而不是
PLACE1_LONGITUDE