从plist中获取选定的MapAnnotation详细信息

时间:2013-02-18 07:10:15

标签: ios objective-c mkmapview plist

我正在尝试获取用户点击MapAnnotation的特定详细信息。详细信息是从plist文件中提取的。对于这个函数,我使用了- (void)mapView:(MKMapView *)mapView didSelectAnnotationView:(MKAnnotationView *)view; 使用this.while我点击特定annotation它从Map获取位置详细信息为"Pune, Maharashtra, India @ <+18.50565666,+73.85559082> +/- 0.00m"并且它不会检查我的plist值。甚至在我将这些值作为plist中的属性给出之后latlong为每个location.can任何人解决我的问题?

我的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工作正常。但是在获取所选位置时它只是不工作。任何人都可以帮助我哪里出错?

提前致谢。

1 个答案:

答案 0 :(得分:3)

didSelectAnnotationView方法中,您似乎在遍历arrayImages,正在寻找latlong == newIndex的人。几点想法:

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

  2. 无论如何,如果我遵循你的逻辑,即使相等运算符确实有效,我也不是很完美,因为在geocodeRequest中你正在从MKPlacemark创建一个新的allValues },但在didSelectAnnotationView中,您将其与arrayImages进行比较。 if中的didSelectAnnotationView语句正在查看latlongnewIndex(前者我没有看到你设置,后者是一个注释数组)。这对我来说没有意义。我看不出他们怎么可能匹配。

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

    有关自定义注释的示例,请参阅位置感知编程指南的Defining a Custom Annotation Object部分。一旦您定义了自己的注释子类,其中包含您认为的所有额外属性然后,您需要(a)更改您的geocodeRequest以创建新注释子类的实例,而不是MKPlacemark; (b)将didSelectAnnotationView更改为仅从annotationannotationView的属性)中获取必要的数据。这样,它完全消除了迭代查找匹配的可能注释列表的麻烦。

  4. 仅供参考,在另一个S.O. answer中,我举例说明了处理标注,弹出窗口等方面的选项,所以也许有些东西可能对你有用。我不在那里使用自定义注释,但也许它会为您提供有关与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];
    

    或者,如果您想利用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
    }