注释引脚标题显示所有引脚的相同标题。我已设置标签以显示每个引脚的标题,但我获得所有标签的相同标题。我做了NSLog lbl.text和NSLog中显示不同的标题。
为什么我为所有地图引脚获得相同的标题。
-(void)maprequests
{
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
// getting an NSString
NSString *emailid = [prefs stringForKey:@"email"];
NSString *deviceid = [Request UDID];
//NSString * walkGUID=[prefs stringForKey:@"walkguid"];
//NSLog(@"walkGUID:%@",walkGUID);
NSString * walkguid=[prefs stringForKey:@"walkguid"];
NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@"http://10.0.0.28/web/ws/get_poilist_walks.php?strEmailID=%@&strDeviceID=%@&strWalkGuid=%@",emailid,deviceid,walkguid]];
NSLog(@"%@",url);
NSURLRequest *request = [NSURLRequest requestWithURL:url];
//AFNetworking asynchronous url request
AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
operation.responseSerializer = [AFJSONResponseSerializer serializer];
operation.responseSerializer.acceptableContentTypes = [NSSet setWithObject:@"text/html"];
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
self.pointofintrests = [responseObject objectForKey:@"PointOfIntrests"];
NSIndexPath *indexpath;
NSDictionary *tempDictionary= [self.pointofintrests objectAtIndex:indexpath.row];
for (NSDictionary *dictionary in _pointofintrests)
{
MKCoordinateRegion region = { {0.0, 0.0 }, { 0.0, 0.0 } };
NSString * latitude= [dictionary objectForKey:@"Latitude"];
NSString * longitude =[dictionary objectForKey:@"Longitude"];
double strlatitude = [latitude doubleValue];
double strlongitude = [longitude doubleValue];
region.center.latitude =strlatitude;
region.center.longitude = strlongitude;
region.span.longitudeDelta = 0.01f;
region.span.latitudeDelta = 0.01f;
[_mapview setRegion:region animated:YES];
[_mapview setDelegate:self];
DisplayMap *ann = [[DisplayMap alloc] init];
ann.coordinate = region.center;
[_mapview addAnnotation:ann];
}
}
failure:^(AFHTTPRequestOperation *operation, NSError *error)
{
NSLog(@"Request Failed: %@, %@", error, error.userInfo);
}];
[operation start];
}
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation{
MKPinAnnotationView *pinView = nil;
UILabel *label;
if(annotation != mapView.userLocation)
{
static NSString *defaultPinID = @"com.invasivecode.pin";
pinView = (MKPinAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:defaultPinID];
if ( pinView == nil ) pinView = [[MKPinAnnotationView alloc]
initWithAnnotation:annotation reuseIdentifier:defaultPinID];
if(![annotation isKindOfClass:[DisplayMap class]])
return nil;
DisplayMap *a = (DisplayMap *)annotation;
pinView.image=[UIImage imageNamed:@"push_pin@2x"];
UILabel *lbl = [[UILabel alloc] initWithFrame:CGRectMake(10, 30, 250, 30)];
lbl.backgroundColor = [UIColor clearColor];
lbl.textColor = [UIColor whiteColor];
lbl.alpha = 0.5;
lbl.tag = 42;
for (int i=0; i<_pointofintrests.count; i++)
{
lbl.text = [[_pointofintrests valueForKey:@"title"] objectAtIndex:i];
}
[pinView addSubview:lbl];
[_mapview selectAnnotation:pinView animated:YES];
pinView.canShowCallout = YES;
pinView.animatesDrop = NO;
}
else
{
}
return pinView;
}
答案 0 :(得分:0)
您的问题是您正在循环_pointofinterests
for (int i=0; i<_pointofintrests.count; i++)
{
lbl.text = [[_pointofintrests valueForKey:@"title"] objectAtIndex:i];
}
这不符合你的想法。它将数组中的最后一个标题分配给每个引脚。
因为viewForAnnotation
委托方法为您提供了将要显示的注释,我倾向于保留一组注释来保存索引,因此您可以正确访问数据。
当您致电[_mapview addAnnotation:ann];
时,也会将ann
保存到数组中。
然后你应该能够做出类似的事情:
[[_pointofintrests valueForKey:@"title"] objectAtIndex:[annArray indexOfObject:annotation]]
作为旁注,如果_pointofinterests
是NSDictionary
,我会改用objectForKey
。
答案 1 :(得分:0)
正如在另一个答案中已经指出的那样,在所有引脚上获得相同标签文本的主要原因是,对于每个引脚,lbl.text
始终设置为{{1}中最后一个对象的标题}}
我更喜欢的解决方案是设置注释_pointofintrests
并使用它来设置标签的文本。
创建注释时,在调用title
之前,请设置其addAnnotation
属性:
title
在DisplayMap *ann = [[DisplayMap alloc] init];
ann.coordinate = region.center;
ann.title = [dictionary objectForKey:@"title"]; //<-- add this line
[_mapview addAnnotation:ann];
中,您可以简单地将标签的文本设置为注释的标题(不搜索数组或循环),而不是viewForAnnotation
循环:
for
这在技术上解决了所有引脚上出现相同文本的问题。
但是,//for (int i=0; i<_pointofintrests.count; i++)
//{
// lbl.text = [[_pointofintrests valueForKey:@"title"] objectAtIndex:i];
//}
lbl.text = annotation.title;
中的代码还存在其他一些问题,这些问题在上述修复后会变得明显:
即使注释视图已出列(意味着正在重新使用先前创建的视图),viewForAnnotation
也会添加到注释视图中。该出列的视图已经其中包含UILabel
,现有代码将在顶部添加另一个。平移和缩放地图一段时间后,您会注意到每个图钉的重叠标签。
UILabel
只应在创建新视图时添加(当出列队列返回UILabel
而你nil
+ alloc
新的视图时)。 强>
另一个问题是,由于您使用自定义图片作为注释,因此应创建普通init
而不是MKAnnotationView
。 MKPinAnnotationView
类用于显示标准的内置图钉图像,虽然它仍具有MKPinAnnotationView
属性,但有时会忽略它并恢复显示其标准图钉图像。
另一个问题是这一行:
image
[_mapview selectAnnotation:pinView animated:YES];
中调用它会同时显示所有注释的标注,那就错了。viewForAnnotation
方法需要注释作为第一个参数。 selectAnnotation
不是注释 - 它是注释的视图(它们不是同一个东西)。编译器必须抱怨此行,并且在运行时,系统可能在控制台中显示错误,例如“尝试选择尚未添加的注释”。从技术上讲,该行应为pinView
[_mapview selectAnnotation:annotation animated:YES];
。这样做可能会导致递归和堆栈溢出(以及EXC_BAD_ACCESS),因为select会导致要更新的注释视图会导致调用viewForAnnotation等。而是在selectAnnotation
委托方法中为要显示标注的 one 注释调用它。您修改后的viewForAnnotation
委托方法可能如下所示:
didAddAnnotationViews
请记住,您还需要设置注释的viewForAnnotation
,如答案顶部所示。
我想指出-(MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation
{
if(! [annotation isKindOfClass:[DisplayMap class]])
{
return nil;
}
static NSString *defaultPinID = @"MyPin";
int lblTag = 42;
MKAnnotationView *pinView = [mapView dequeueReusableAnnotationViewWithIdentifier:defaultPinID];
if (pinView == nil)
{
pinView = [[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:defaultPinID];
pinView.image = [UIImage imageNamed:@"push_pin@2x"];
pinView.canShowCallout = YES;
//Create and add the label to the view ONCE when creating the view...
UILabel *lbl = [[UILabel alloc] initWithFrame:CGRectMake(10, 30, 250, 30)];
lbl.backgroundColor = [UIColor clearColor];
lbl.textColor = [UIColor whiteColor];
lbl.alpha = 0.5;
lbl.tag = lblTag;
[pinView addSubview:lbl];
}
else
{
//If we are re-using a dequeued view
//update its annotation reference...
//(otherwise view will still be pointing to its previous annotation)
pinView.annotation = annotation;
}
//At this point, we have a new or dequeued view
//pointing to the current annotation.
//Now update the label that will already be there
//with the current annotation's title...
UILabel *lbl = (UILabel *)[pinView viewWithTag:lblTag];
lbl.text = annotation.title;
return pinView;
}
方法中的title
循环中还有一些内容:
没有必要创建和设置区域只是为了设置注释的坐标。在循环中调用for
是没有意义且效率低的,因为用户最终只会看到位于最后一个注释的地图。要设置注释坐标,只需执行:
maprequests
您可以在 setRegion
循环之后致电ann.coordinate = CLLocationCoordinate2DMake(strlatitude, strlongitude);
(一次)(或只需致电setRegion
,这样您就无需自行计算显示所有注释的区域。
您无需反复在for
循环内设置地图视图的[_mapview showAnnotations:_mapview.annotations animated:YES];
。在 delegate
循环之前设置for
(一次)(尽管在调用此方法之前应该已经设置了很久)。