将Parse PFobject objectID传递给地图注释视图按钮标题 [英] Pass Parse PFobject objectID to map annotation view button title
问题描述
我有一个注释视图设置,将UIButton添加到rightCalloutAccessoryView.我想做的是将按钮的标题设置为注释表示的解析对象的objectID.
I have an annotation view setup that adds a UIButton to rightCalloutAccessoryView. What I am trying to do is set the title of the button to the objectID of the parse object that the annotation represents.
我当前的结果是每个注释都将获取查询中第一个对象的objectID.我在这里做什么错了?
My current result is that every annotation is getting the objectID of the first object in the query. What am I doing wrong here?
看下面我发现的代码,每次在地图上放置图钉时都不会设置restaurantID.在我看来,由于引脚的标题和副标题正确更新,因此我将其放置在正确的位置.
Looking at the code below what I am finding is that restaurantID is not being set each time a pin drops on the map. It seems to me I have it in the correct place as the title and subtitle of the pins update correctly.
这是我所做的:
1.)在我的mainViewController.h中,我声明了一个字符串来保存PFobject的objectID:
1.) In my mainViewController.h I have declared a string to hold the objectID of the PFobject:
@property (strong, nonatomic) NSString *restaurantID;
2.)在我的mainViewController.m中,我已经合成了变量
2.) In my mainViewController.m I have synthesized the variable
@synthesize restaurantID;
3.)在我的PFquery中,我将此restaurantID设置为PFobject的objectID(restaurantID = [object objectId];):
3.) In my PFquery I am setting this restaurantID to the objectID of the PFobject ( 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];
}
然后在我的注释视图中,将按钮的标题设置为restaurantID:
Then in my annotation view I set the title of the button to be the restaurantID:
UIButton* rightButton = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
[rightButton setTitle:restaurantID forState:UIControlStateNormal];
[rightButton addTarget:self
action:@selector(buttonMethod:)
forControlEvents:UIControlEventTouchUpInside];
在我的buttonMethod中:我有一个NSLog来显示按下的按钮的标题.该值保持不变,因为我单击了不同的引脚.它会获取一个Parse对象的objectID,但不会为查询中的每个对象获取新的objectID.
In my buttonMethod: I have an NSLog to display the title of the button pressed. The value remains the same as I click on different pins. It grabs the objectID of one Parse object, but it is not grabbing a new objectID for each object in the query.
有什么想法吗?
推荐答案
在调用addAnnotation
nor 后必须立即调用
The viewForAnnotation
delegate is not necessarily called immediately after you call addAnnotation
nor is it necessarily called only once for each annotation.
当地图视图想要显示注释时,它将调用委托方法.这可能会比您添加时晚一些,或者如果用户平移或缩放地图并且该注释再次出现在屏幕上,则对于同一注释可能再次发生.
The map view will call the delegate method when it wants to show the annotation. This may happen a little later than when you add it or it could happen again for the same annotation if the user pans or zooms the map and the annotation comes onto the screen again.
因此,您不能按原样使用view-controller-level restaurantID
变量(假设它只是相对于地图视图正在调用viewForAnnotation
的注释设置的).到地图视图调用viewForAnnotation
时,restaurantID
设置为与该地图视图当前为其获取的注释无关的某个值.
Therefore, you cannot use the view-controller-level restaurantID
variable the way you are (by assuming that it was just set in relation to the annotation the map view is calling viewForAnnotation
for). By the time the map view calls viewForAnnotation
, restaurantID
is set to some value that is unrelated to the annotation the map view is currently getting the view for.
相反,您应该将objectId
(甚至整个object
)分别放在每个注释 中.
Instead, you should put the objectId
(or even the whole object
) in each annotation individually.
现在,由于使用的是MKPointAnnotation
类,因此只能设置的属性是coordinate
,title
和subtitle
.
Right now, since you're using the MKPointAnnotation
class, the only properties you can set are coordinate
, title
, and subtitle
.
您需要子类化MKPointAnnotation
或创建自己的实现MKAnnotation
协议的自定义类,并向其中添加restaurantID
属性.
You need to subclass MKPointAnnotation
or create your own custom class that implements the MKAnnotation
protocol and add a restaurantID
property to it.
在添加注释时设置此属性:
Set this property when adding the annotation:
CustomAnnotationClass *foodPoint = [[CustomAnnotationClass alloc] init];
foodPoint.coordinate = (spot);
foodPoint.restaurantID = [object objectId]; //<--put objectId in foodPoint
foodPoint.title = [object objectForKey:@"restaurantName"];
然后在viewForAnnotation
中,使用annotation
参数获取与地图视图当前要求的注释相关的值:
Then in viewForAnnotation
, use the annotation
parameter to get the values relevant to the annotation the map view is currently calling for:
//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;
).如果不这样做,则视图或标注又可能会显示其他注释的数据.
Also be sure to handle annotation view re-use properly. That is, if dequeue
returns a view, update its annotation
property to the current one (eg. annotationView.annotation = annotation;
). If this is not done, it's again possible for the view or callout to show data for a different annotation.
可以通过显示错误标题的按钮来解决该问题.
That should resolve the issue with the button showing the wrong title.
但是,我假设您只是在设置按钮的标题,这样您才能弄清楚用户点击了哪个注释.这样可以工作",但有点麻烦,因为标题(restaurantID)将显示在公开图标的右侧(尽管在标注中可能看不到).
However, I assume you're setting the button's title just so you can figure out which annotation the user tapped. That will "work" but it's a bit kludgy since the title (restaurantID) will appear to the right of the disclosure icon (though it may not be visible in the callout).
我强烈建议您使用地图视图的calloutAccessoryControlTapped
委托方法或地图视图的selectedAnnotations
属性来代替该方法.有关示例,请参见以下问题:
Instead of that approach, I highly recommend using the map view's calloutAccessoryControlTapped
delegate method or the map view's selectedAnnotations
property. See these questions for examples:
- How to recognize which pin was tapped
- How to keep data associated with MKAnnotation from being lost after a callout pops up and user taps disclosure button?
这样,您可以获取对注释对象本身的引用,并从中获取restaurantID(与viewForAnnotation
中的方法相同).
This way, you can get a reference to the annotation object itself and from that get the restaurantID (same way as in viewForAnnotation
).
这篇关于将Parse PFobject objectID传递给地图注释视图按钮标题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!