我正在尝试获取用户点击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工作正常。但是在获取所选位置时它只是不工作。任何人都可以帮助我哪里出错?
提前致谢。
答案 0 :(得分:3)
在didSelectAnnotationView
方法中,您似乎在遍历arrayImages
,正在寻找latlong == newIndex
的人。几点想法:
使用等于运算符==
来比较对象,通常不是一种谨慎的技巧。您无法保证地图视图的注释是同一个对象(如果它们的属性使用copy
,它将不相等,因为您的对象和他们的地址可能不同)。即使它确实发生了工作,也不是非常可靠的工作方式。
无论如何,如果我遵循你的逻辑,即使相等运算符确实有效,我也不是很完美,因为在geocodeRequest
中你正在从MKPlacemark
创建一个新的allValues
},但在didSelectAnnotationView
中,您将其与arrayImages
进行比较。 if
中的didSelectAnnotationView
语句正在查看latlong
和newIndex
(前者我没有看到你设置,后者是一个注释数组)。这对我来说没有意义。我看不出他们怎么可能匹配。
但这两个先前的观点是无关紧要的,因为正确的解决方案是不将MKPlacemark
添加到地图中,然后在didSelectAnnotationView
寻找匹配的情况下遍历您的列表,而是,创建自己的注记类,其中包含您希望在用户点击注释视图时能够检索的所有属性。或者,至少,拥有自己的注释子类并定义一个属性,您可以使用该属性从数组中查找特定的详细信息。两种方法都有效。但关键是不要试图迭代你的对象寻找匹配,而是定义一个自定义注释,其中包含你需要立即找到它的所有东西。
有关自定义注释的示例,请参阅位置感知编程指南的Defining a Custom Annotation Object部分。一旦您定义了自己的注释子类,其中包含您认为的所有额外属性然后,您需要(a)更改您的geocodeRequest
以创建新注释子类的实例,而不是MKPlacemark
; (b)将didSelectAnnotationView
更改为仅从annotation
(annotationView
的属性)中获取必要的数据。这样,它完全消除了迭代查找匹配的可能注释列表的麻烦。
仅供参考,在另一个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
}