3

我正在尝试获取MapAnnotation用户单击的特定详细信息。详细信息是从plist文件中获取的。对于我在使用此功能- (void)mapView:(MKMapView *)mapView didSelectAnnotationView:(MKAnnotationView *)view; 时使用过的此功能。当我单击特定时,它会从as annotation获取位置详细信息,并且它不会检查我的 plist 值。即使在我将这些值作为 plist 中的属性作为每个位置的 latlong 给出之后。任何人都可以解决我的问题?Map"Pune, Maharashtra, India @ <+18.50565666,+73.85559082> +/- 0.00m"

我的 plist 文件详细信息:

2013-02-18 12:16:56.039 MapView[9407:13d03] {
contents = "This Fish will be Found Rarely in South Asia";
imagesName = "kfish.jpg";
latlong = "Bangalore, Karnataka, India @ <+12.98333330,+77.58333330> +/- 0.00m";
listName = kFish;
location = "Bangalore, Karnataka, India";
}
2013-02-18 12:16:56.039 MapView[9407:13d03] {
contents = "This Fish will be Found Rarely in South Asia";
imagesName = "wallfish.png";
latlong = "Delhi, India @ <+28.59100531,+77.08826373> +/- 0.00m";
listName = WallFish;
location = "Delhi, India";
}
2013-02-18 12:16:56.039 MapView[9407:13d03] {
contents = "This Fish will be Found Rarely in South Asia";
imagesName = "fish.jpg";
latlong = "Chennai, Tamil Nadu, India @ <+13.07983465,+80.24625757> +/- 0.00m";
listName = Fish;
location = "Chennai,TamilNadu,India";
}

2013-02-18 12:16:56.039 MapView[9407:13d03] {
contents = "This Fish will be Found Rarely in South Asia";
imagesName = "bluefish.jpg";
latlong = "Mumbai, Maharashtra, India @ <+18.99460885,+72.82287598> +/- 0.00m";
listName = BlueFish;
location = "Mumbai, Maharashtra, India";
}

2013-02-18 12:16:56.040 MapView[9407:13d03] {
contents = "This Fish will be Found Rarely in South Asia";
imagesName = "Rarefish.jpg";
latlong = "Chennai, Tamil Nadu, India @ <+13.07983465,+80.24625757> +/- 0.00m";
listName = RareFish;
location = "Chennai,TamilNadu,India";
}

我的编码:

- (void)geocodeRequest
{
CLGeocoder *geocoder = [[CLGeocoder alloc]init];
for (int i = 0; i < total; i++) {
    NSString *address = [allValues objectAtIndex:i] ;

            [geocoder geocodeAddressString:address completionHandler:^(NSArray *placemarks, NSError *error) {
                        CLPlacemark *geocodedPlacemark = [placemarks objectAtIndex:0];
                        MKPlacemark *placemark = [[MKPlacemark alloc] initWithCoordinate:geocodedPlacemark.location.coordinate addressDictionary:geocodedPlacemark.addressDictionary];

                        int zoomLevel=20;
                        MKCoordinateRegion region=MKCoordinateRegionMake(geocodedPlacemark.location.coordinate, MKCoordinateSpanMake(zoomLevel,zoomLevel));
                        [self.mapView addAnnotation:placemark];
                        [self.mapView setRegion:region animated:YES];
                        [self.mapView setZoomEnabled:YES];
                                  }];

}


-(void)mapView:(MKMapView *)mapView didSelectAnnotationView:(MKAnnotationView *)view{
    total = self.arrayImages.count;
NSArray *newIndex = [mapView selectedAnnotations];
NSLog(@"sel :%@",newIndex);

    for (index = 0; index < total; index++) {
        dict = [self.arrayImages objectAtIndex:index];
        NSLog(@"%@",dict);

        if (latlong == newIndex) {

            CGRect rec = CGRectMake(0, 0, 250, 250);
            [self setView:[[[UIView alloc] initWithFrame:rec] autorelease]];
            [[self view] setBackgroundColor:[UIColor whiteColor]];
            UIImage *img = [UIImage imageNamed:[dict objectForKey:@"imagesName"]];

            UIImageView *im = [[UIImageView alloc] initWithImage:img];
            UILabel *lab1 = [[UILabel alloc] init];
            UITextView *detailsView = [[UITextView alloc] init];
            lab1.text = [NSString stringWithFormat:[dict objectForKey:@"listName"]];
            detailsView.text = [NSString stringWithFormat:[dict objectForKey:@"contents"]];
            detailsView.editable = NO;
            detailsView.bounds = CGRectMake(20, 20, 150, 150);
            detailsView.frame = CGRectMake(210, 720, 390, 350);
            detailsView.font = [UIFont systemFontOfSize:24];

            lab1.bounds = CGRectMake(20, 20, 150, 150);
            lab1.frame = CGRectMake(360, 600, 90, 50);
            lab1.font = [UIFont systemFontOfSize:24];
            im.bounds = CGRectMake(10, 10, 50, 50);
            im.frame = CGRectMake(200, 120, 370, 450);

        [UIView transitionWithView:[self view] duration:1.5
                           options:UIViewAnimationOptionTransitionCurlUp
                        animations:^ { [[self view] addSubview:im];
                                       [[self view] addSubview:lab1];
                                       [[self view] addSubview:detailsView];

         }completion:nil];
        }
    }


}

MapView 工作正常。但仅在获取所选位置时它不起作用。谁能帮我我哪里出错了?

提前致谢。

4

1 回答 1

3

在您的didSelectAnnotationView方法中,您似乎正在遍历您arrayImageslatlong == newIndex. 几个想法:

  1. 使用相等运算符==来比较对象通常不是一种谨慎的技术。您无法保证地图视图的注释是同一个对象(如果它们的属性使用copy,则它不会相等,因为您的对象的地址和它们的地址可能不同)。即使它确实发生了,它也不是非常可靠的工作方式。

  2. 无论如何,如果我遵循你的逻辑,我并不完全符合你的逻辑,即使相等运算符确实有效,因为geocodeRequest你正在制作一个 new MKPlacemark, from allValues,但didSelectAnnotationView你正在将它与arrayImages. 并且您的if声明didSelectAnnotationView正在查看latlongnewIndex(前者我没有看到您设置,后者是一组注释)。这对我来说没有意义。我看不出他们怎么可能匹配。

  3. 但是前面的两点是无关紧要的,因为正确的解决方案是不要将您添加MKPlacemark到您的地图中,然后在寻找匹配项时遍历您的列表didSelectAnnotationView,而是使用您想要的所有属性创建您自己的注释类能够在用户点击注释视图时检索。或者,至少,拥有您自己的注释子类并定义一个属性,您可以使用该属性从您的数组中查找特定的详细信息。任何一种方法都有效。但关键是不要尝试遍历您的对象以寻找匹配项,而是定义一个自定义注释,其中包含您立即找到它所需的一切。

    有关自定义注释的示例,请参阅位置感知编程指南的定义自定义注释对象部分。一旦您使用您认为需要的所有额外属性定义了自己的注释子类,您将 (a) 更改您以创建新注释子类的实例,而不是; (b) 将您的更改为仅从(这是 的属性)中获取必要的数据。这样,它就完全消除了遍历可能的注释列表以寻找匹配项的麻烦。geocodeRequestMKPlacemarkdidSelectAnnotationViewannotationannotationView

仅供参考,在另一个SO 答案中,我给出了一些关于处理标注、弹出框等选项的示例,所以也许那里有一些对你有帮助的背景知识。我不在那里使用自定义注释,但也许它会给你一些关于与 MapKit 集成的想法。


让我来说明一下这种做法。假设我们想要注释我们的地图,但想要跟踪其他属性。首先,我将定义一个具有我的附加属性的注释自定义类。(我将把它从子类化MKPointAnnotation,让我的生活更轻松一些。)

@interface CustomAnnotation : MKPointAnnotation

@property (nonatomic) NSUInteger index;
@property (strong, nonatomic) NSString *property1;
@property (strong, nonatomic) NSString *property2;
@property (strong, nonatomic) NSString *property3;

@end

现在,当我想将注释添加到我的地图视图时,我将使用我的自定义注释类,确保设置我想要的任何属性。您可以将数字索引保存在数组中,或保存您关心的实际属性,或两者兼而有之:

CustomAnnotation *annotation = [[CustomAnnotation alloc] init];

// set the MKPointAnnotation standard properties

annotation.title = item.name;
annotation.coordinate = item.placemark.coordinate;

// set my custom properties

annotation.index = idx;
annotation.property1 = ...;
annotation.property2 = ...;
annotation.property3 = ...;

// now add the annotation to the map view

[annotations addObject:annotation];

或者,如果您想利用 a 的所有属性MKPlacemark,您可以执行以下操作:

@interface CustomAnnotation : MKPlacemark

@property (strong, nonatomic) NSString *title; // MKPlacemark doesn't have title, so let's add our own property for that
@property (nonatomic) NSUInteger index;
@property (strong, nonatomic) NSString *property1;
@property (strong, nonatomic) NSString *property2;
@property (strong, nonatomic) NSString *property3;

@end

您可以像创建 一样创建注释MKPlacemark,但再次设置我们的自定义属性:

CustomAnnotation *annotation = [[CustomAnnotation alloc] initWithPlacemark:item.placemark];

// set my custom properties

annotation.title = item.name;
annotation.index = idx;
annotation.property1 = ...;

[annotations addObject:annotation];

现在,当我选择注释视图时,我可以相应地处理:

- (void)mapView:(MKMapView *)mapView didSelectAnnotationView:(MKAnnotationView *)view
{
    if ([view.annotation isKindOfClass:[CustomAnnotation class]])
    {
        CustomAnnotation *annotation = view.annotation;

        // note, I don't have to iterate through any arrays to figure out which
        // annotation I'm dealing with; I can just look at my custom properties

        NSLog(@"index = %d; property1 = %@", annotation.index, annotation.property1);

        // now do whatever you want with that annotation; I could look up the
        // annotations's details by using the custom `index` property I defined,
        // or if I defined my annotations to store all of the detail properties
        // I needed, I can just access them directly
    }
}

didSelectAnnotationView顺便说一句,您可能希望采用更标准的行为,而不是使用MKMapView,并显示标准标注气泡,设置正确的标注气泡附件,然后处理单击该标注附件:

- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation
{
    if (![annotation isKindOfClass:[CustomAnnotation class]])
        return nil;

    MKAnnotationView *annotationView = [[MKPinAnnotationView alloc] initWithAnnotation:annotation
                                                                       reuseIdentifier:@"CustomAnnotationView"];
    annotationView.canShowCallout = YES;
    annotationView.rightCalloutAccessoryView = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
    
    return annotationView;
}

- (void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view calloutAccessoryControlTapped:(UIControl *)control
{
    if (![view.annotation isKindOfClass:[CustomAnnotation class]])
        return;

    CustomAnnotation *annotation = view.annotation;

    // note, I don't have to iterate through any arrays to figure out which
    // annotation I'm dealing with; I can just look at my custom properties

    NSLog(@"index = %d; property1 = %@", annotation.index, annotation.property1);

    // now do whatever you want with that annotation; I could look up the
    // annotations's details by using the custom `index` property I defined,
    // or if I defined my annotations to store all of the detail properties
    // I needed, I can just access them directly
}
于 2013-02-18T08:24:40.503 回答