通过分析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的restaurantID
variables(通过假定它只是和地图视图调用viewForAnnotation
的注解有关)。 在地图视图调用viewForAnnotation
, restaurantID
被设置为与地图视图当前正在获取视图的注释无关的某个值。
相反,你应该把objectId
(甚至整个object
)分别放在每个注释中。
现在,由于您正在使用MKPointAnnotation
类,因此您可以设置的唯一属性是coordinate
, title
和subtitle
。
您需要子类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
方法相同)。