在ios中创建自定义详图索引

在ios中创建自定义详图索引,ios,cocoa-touch,mkmapview,mkannotationview,Ios,Cocoa Touch,Mkmapview,Mkannotationview,我想在地图上创建自定义详图索引。我现在已经试过了- -(void)mapView:(MKMapView *)mapView didSelectAnnotationView:(MKAnnotationView *)view{ NSLog(@"ANNNOTATION VIEW : %@", view); NSLog(@"VIEW ANNOTATION: %@", view.annotation); MyMapAnnotationViewController* mapA

我想在地图上创建自定义详图索引。我现在已经试过了-

    -(void)mapView:(MKMapView *)mapView didSelectAnnotationView:(MKAnnotationView *)view{
    NSLog(@"ANNNOTATION VIEW : %@", view);
    NSLog(@"VIEW ANNOTATION: %@", view.annotation);
    MyMapAnnotationViewController* mapAnnotationViewController = [[MyMapAnnotationViewController alloc]initWithNibName:@"MapAnnotationView" bundle:nil];
    MyLocation* location = (MyLocation*)view.annotation;
    [mapAnnotationViewController setTitle: [location title]];
    [mapAnnotationViewController setRating:3.0];
    [view addSubview:mapAnnotationViewController.view];   
}

-(void)viewWillAppear:(BOOL)animated{
    [_mapView setRegion: _viewRegion];
    for (id<MKAnnotation> annotation in _mapView.annotations) {
        [_mapView removeAnnotation:annotation];
    }
    for(NSDictionary* result in _resultsToPlot){
        NSString* address = someAddr;
        NSString* restaurantTitle = someTitle;
        NSString* description = someDescription;
        NSString* lonLat = someLonLat;
        NSArray *list = [lonLat componentsSeparatedByString:@";"];
        CLLocationCoordinate2D coordinate;
        coordinate.longitude = [[list objectAtIndex: 1] doubleValue];
        coordinate.latitude = [[list objectAtIndex: 0] doubleValue];
        MyLocation *annotation = [[MyLocation alloc] initWithName:restaurantTitle address:address coordinate:coordinate] ;

        [_mapView addAnnotation:annotation];
    }
我现在得到这个错误-

NSInvalidArgumentException', reason: '-[MyLocation setCanShowCallout:]: unrecognized selector sent to instance 0xcb683e0'

要禁止显示内置详图索引,请在
viewForAnnotation
委托方法中的
MKPinAnnotationView
/
MKAnnotationView
上将
canShowCallout
设置为
NO

下一个问题是,当前代码始终在创建新的自定义详图索引视图,并将其添加到选定注释的视图中。这就是为什么会同时显示多个详图索引(之前选定的标注上的标注不会被删除)

一种解决方案是保留自定义详图索引视图的单个实例,而不是每次选择注释时都创建一个新实例。然后,选择或取消选择注释时,只需添加/删除详图索引视图

在包含地图视图的视图控制器中将此单个实例声明为强属性:

@property (nonatomic, strong) MyMapAnnotationViewController* mapAnnotationViewController;
viewdiload
中创建详图索引实例(或
viewwillbeen
,如果这样做对您有效),但此时不要将其作为子视图添加到任何位置,只需创建它:

self.mapAnnotationViewController = [[MyMapAnnotationViewController alloc...
didSelectAnnotationView
中,不要创建新的详图索引视图实例,而是告诉现有实例从其当前超级视图(如果有)中删除自身,然后将其添加到新注释的视图中:

-(void)mapView:(MKMapView *)mapView didSelectAnnotationView:(MKAnnotationView *)view {
    NSLog(@"ANNNOTATION VIEW : %@", view);
    NSLog(@"VIEW ANNOTATION: %@", view.annotation);

    [self.mapAnnotationViewController.view removeFromSuperview];

    MyLocation* location = (MyLocation*)view.annotation;
    [self.mapAnnotationViewController setTitle: [location title]];
    [self.mapAnnotationViewController setRating:3.0];
    //Since we are re-using the callout view, 
    //may need to do additional "cleanup" so that the callout
    //shows the new annotation's data.

    [view addSubview:self.mapAnnotationViewController.view];   
}
最后,您需要处理这样的情况:用户通过点击地图(而不是另一个注释)取消选择注释,只需删除详图索引视图:

-(void)mapView:(MKMapView *)mapView didDeselectAnnotationView:(MKAnnotationView *)view
{
    [self.mapAnnotationViewController.view removeFromSuperview];
}

viewForAnnotation
delegate方法应如下所示:

-(MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation
{
    if (! [annotation isKindOfClass:[MyLocation class]])
    {
        //tell map view to show default view for annotations other than ours
        //(like the user location blue dot)
        return nil;
    }

    MKPinAnnotationView *pav = (MKPinAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:@"pin"];
    if (pav == nil)
    {
        pav = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:@"pin"];
        pav.canShowCallout = NO;
    }
    else
    {
        pav.annotation = annotation;
    }

    return pav;
}
-(MKAnnotationView*)地图视图:(MKMapView*)地图视图注释:(id)注释
{
if(![annotation isKindOfClass:[MyLocation class]])
{
//告诉map view显示注释的默认视图,而不是我们的注释
//(如用户位置蓝点)
返回零;
}
MKPinAnnotationView*pav=(MKPinAnnotationView*)[mapView出列重用AnnotationView,标识符:@“pin”];
如果(pav==nil)
{
pav=[[MKPinAnnotationView alloc]initWithAnnotation:annotation重用标识符:@“pin”];
pav.canShowCallout=否;
}
其他的
{
pav.annotation=注释;
}
返回pav;
}

因此viewForAnnotation方法给了我一个,而不是MKAnnotationView-这就是您所说的方法吗?我将添加一个示例,说明
viewForAnnotation
方法应该是什么样子。谢谢-我已经在这方面停留了一段时间,似乎有很多解决方案和很多代码注释的模型对象是MKAnnotation类型,并且这里有一个视图对象,它的类型是MKAnnotationView。在viewForAnnotation中,创建并返回模型的视图。
-(MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation
{
    if (! [annotation isKindOfClass:[MyLocation class]])
    {
        //tell map view to show default view for annotations other than ours
        //(like the user location blue dot)
        return nil;
    }

    MKPinAnnotationView *pav = (MKPinAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:@"pin"];
    if (pav == nil)
    {
        pav = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:@"pin"];
        pav.canShowCallout = NO;
    }
    else
    {
        pav.annotation = annotation;
    }

    return pav;
}