将Parse PFobject objectID传递给地图注释视图按钮标题 [英] Pass Parse PFobject objectID to map annotation view button title

查看:55
本文介绍了将Parse PFobject objectID传递给地图注释视图按钮标题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个注释视图设置,将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类,因此只能设置的属性是coordinatetitlesubtitle.

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆