通过分析PFobject objectID来映射注解视图button标题

我有一个注释视图设置,添加一个UIButton到rightCalloutAccessoryView。 我想要做的是将button的标题设置为注释表示的parsing对象的objectID。

我当前的结果是每个注释都获取查询中第一个对象的对象ID。 我在这里做错了什么?

看看下面的代码,我发现,每当一个针脚落在地图上,餐厅ID都没有被设置。 在我看来,我把它放在正确的位置,因为引脚的标题和副标题正确更新。

这是我所做的:

1.)在我的mainViewController.h我已经声明了一个string来保存PFobject的objectID:

@property (strong, nonatomic) NSString *restaurantID; 

2)在我的mainViewController.m我已经合成了variables

 @synthesize restaurantID; 

3.)在我的PFquery中,我将这个restaurantID设置为PFobject的对象ID(restaurantID = [object objectId];):

  for (PFObject *object in objects) { PFGeoPoint *point = [[object objectForKey:@"geoLocation"] init]; CLLocationCoordinate2D spot; spot.latitude = point.latitude; spot.longitude = point.longitude; MKPointAnnotation *foodPoint = [[MKPointAnnotation alloc] init]; foodPoint.coordinate = (spot); restaurantID = [object objectId]; foodPoint.title = [object objectForKey:@"restaurantName"]; foodPoint.subtitle = [object objectForKey:@"cuisineType"]; leftIcon = [object objectForKey:@"restaurantImage"]; [leftIcon getDataInBackgroundWithBlock:^(NSData *data, NSError *error) { if (!error) { image = [UIImage imageWithData:data]; // image can now be set on a UIImageView } }]; [self.mainMap addAnnotation:foodPoint]; } 

然后在我的注释视图中,我将button的标题设置为restaurantID:

 UIButton* rightButton = [UIButton buttonWithType:UIButtonTypeDetailDisclosure]; [rightButton setTitle:restaurantID forState:UIControlStateNormal]; [rightButton addTarget:self action:@selector(buttonMethod:) forControlEvents:UIControlEventTouchUpInside]; 

在我的buttonMethod中:我有一个NSLog显示button的标题。 价值保持不变,我点击不同的引脚。 它抓取一个Parse对象的objectID,但不是为查询中的每个对象抓取一个新的objectID。

有任何想法吗?

在您调用addAnnotation之后, viewForAnnotation委托不一定会立即调用, 也不一定每个批注只调用一次。

地图视图将在想要显示注释时调用委托方法。 这可能会比添加它稍晚一些,或者如果用户平移或缩放地图并且注释再次出现在屏幕上,可能会再次出现相同的注释。

因此,不能像你那样使用view-controller-level的restaurantIDvariables(通过假定它只是和地图视图调用viewForAnnotation的注解有关)。 在地图视图调用viewForAnnotationrestaurantID被设置为与地图视图当前正在获取视图的注释无关的某个值。

相反,你应该把objectId (甚至整个object )分别放在每个注释中。

现在,由于您正在使用MKPointAnnotation类,因此您可以设置的唯一属性是coordinatetitlesubtitle

您需要子类MKPointAnnotation或创build自己的自定义类实现MKAnnotation协议并添加restaurantID属性。

添加注释时设置此属性:

 CustomAnnotationClass *foodPoint = [[CustomAnnotationClass alloc] init]; foodPoint.coordinate = (spot); foodPoint.restaurantID = [object objectId]; //<--put objectId in foodPoint foodPoint.title = [object objectForKey:@"restaurantName"]; 

然后在viewForAnnotation ,使用annotation参数来获取与地图视图当前正在调用的注释相关的值:

 //first make sure annotation is our custom type... if ([annotation isKindOfClass:[CustomAnnotationClass class]]) { UIButton* rightButton = [UIButton buttonWithType:UIButtonTypeDetailDisclosure]; //cast annotation parameter to our class so compiler understands... CustomAnnotationClass *fp = (CustomAnnotationClass *)annotation; //get restaurantID from the annotation parameter ("fp")... [rightButton setTitle:fp.restaurantID forState:UIControlStateNormal]; ... } 

另外一定要处理注释视图重新使用正确。 也就是说,如果dequeue返回视图,则将其annotation属性更新为当前视图(例如, annotationView.annotation = annotation; )。 如果没有这样做,视图或标注再次可能显示不同注释的数据。

这应该解决问题,显示错误的标题button。

不过 ,我假设你正在设置button的标题,所以你可以找出用户点击哪个注释。 这将“工作”,但它有点kludgy,因为标题(restaurantID)将出现在披露图标的右侧(虽然它可能不会在标注中可见)。

我强烈build议使用地图视图的calloutAccessoryControlTapped委托方法或地图视图的selectedAnnotations属性来代替这种方法。 请看这些问题的例子:

  • 如何识别哪个引脚被窃听
  • 如何保持与MKAnnotation相关的数据在标注popup并且用户点击泄露button后丢失?

这样,你可以获得对注释对象本身的引用,并从中获取restaurantID(与viewForAnnotation方法相同)。