如何在不触及引脚的情况下触发MKAnnotationView的标注视图?

Teo*_*ing 74 iphone

我正在MKMapView使用通常的彩色针作为位置点.我希望能够在不触碰针的情况下显示标注.

我该怎么办?调用setSelected:YESannotationview什么也没做.我正在考虑模拟针上的触摸,但我不确定如何去做.

小智 62

但有一个问题是让benvolioT的解决方案能够运行,即代码

for (id<MKAnnotation> currentAnnotation in mapView.annotations) {       
    if ([currentAnnotation isEqual:annotationToSelect]) {
        [mapView selectAnnotation:currentAnnotation animated:FALSE];
    }
}
Run Code Online (Sandbox Code Playgroud)

应该从- (void)mapViewDidFinishLoadingMap:(MKMapView *)mapView其他地方调用.

的序列,其中的各种方法喜欢viewWillAppear,viewDidAppearUIViewController并且- (void)mapViewDidFinishLoadingMap:(MKMapView *)mapView被称为是第一次地图被加载有一个特定的位置和后续次地图被显示以相同的位置之间不同.这有点棘手.

  • 确保您的注释视图已准备好显示标注的正确委托方法是@ user507778指出的方法.`MapView类:didAddAnnotationViews:`.这样可以确保加载地图视图,并且还可以放置注释视图并准备好显示标注气泡.任何其他方式可以工作或不工作,具体取决于连接速度,缓存系统,应用程序中断等. (8认同)
  • 没有什么棘手的.只需要知道调用:[mapView selectAnnotation]而不是[annotation setSelected].谢谢! (4认同)
  • mapViewDidFinishLoadingMap仅在缓存地图时首次触发.从缓存加载地图时,不再触发mapViewDidFinishloadingMap. (4认同)

Teo*_*ing 34

好的,这是这个问题的解决方案.

显示callout use MKMapViewselectAnnotation:animated方法.

  • 这没有用.我可以打电话给它,它不会总是为选择设置动画.第一次,是的.每次之后,没有 - 即使调用方法.benvolioT的解决方案也不适用于我.即使我直接调用selectAnnotation:animated:当注释已知时,也不起作用.和以前一样的问题.:( (3认同)

小智 32

假设您希望选择最后一个注释视图,可以将代码放在下面:

[mapView selectAnnotation:[[mapView annotations] lastObject] animated:YES];
Run Code Online (Sandbox Code Playgroud)

在下面的代表中:

- (void)mapView:(MKMapView *)mapView didAddAnnotationViews:(NSArray *)views
{
    //Here
    [mapView selectAnnotation:[[mapView annotations] lastObject] animated:YES];
}
Run Code Online (Sandbox Code Playgroud)


小智 21

好的,要成功添加Callout,您需要调用selectAnnotation:在添加了所有注释视图后使用委托的didAddAnnotationViews进行动画处理:

- (void)mapView:(MKMapView *)mapView didAddAnnotationViews:(NSArray *)views{
    for (id<MKAnnotation> currentAnnotation in mapView.annotations) {       
        if ([currentAnnotation isEqual: annotationToSelect]) {
            [mapView selectAnnotation:currentAnnotation animated:YES];
        }
    }
}
Run Code Online (Sandbox Code Playgroud)


cha*_*e55 12

在尝试了这个线程的各种答案后,我终于想出了这个.它工作非常可靠,我还没有看到它失败:

- (void)mapView:(MKMapView *)aMapView didAddAnnotationViews:(NSArray *)views;
{
    for(id<MKAnnotation> currentAnnotation in aMapView.annotations) 
    {       
        if([currentAnnotation isEqual:annotationToSelect]) 
        {
            NSLog(@"Yay!");
            dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 0.3 * NSEC_PER_SEC), dispatch_get_current_queue(), ^
            {
                [aMapView selectAnnotation:currentAnnotation animated:YES];
            });
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

该块用于稍微延迟,因为没有它可能无法正确显示标注.

  • 难以置信的.这是一个很好的kludge,它处于竞争状态,但它的工作原理.这里的主要内容是,故事板主要处理所有事情,如果你没有在3个月内触及MKMapViews,那么代表需要通过故事板连接起来并不明显.这是故事板应该自动执行的操作,或者至少警告您.我宁愿在init和init上的委托上定义mapKit ref,也不要让storyboard做1/2工作,让你不知道还有另外1/2的工作要做.> 1小时就浪费了. (2认同)

ben*_*ioT 9

这对我不起作用.我怀疑MapKit API中存在一个错误.

有关此人无效的其他人的详细信息,请参阅此链接:http: //www.iphonedevsdk.com/forum/iphone-sdk-development/19740-trigger-mkannotationview-callout-bubble.html#post110447

- 编辑 -

好吧,在搞了一段时间之后,这是我能够做的工作:

for (id<MKAnnotation> currentAnnotation in mapView.annotations) {       
    if ([currentAnnotation isEqual:annotationToSelect]) {
        [mapView selectAnnotation:currentAnnotation animated:FALSE];
    }
}
Run Code Online (Sandbox Code Playgroud)

注意,这需要实现- (BOOL)isEqual:(id)anObject实现MKAnnotation协议的类.


小智 6

如果你只想打开你添加的最后一个注释的标注,试试这个,对我有用.

[mapView selectAnnotation:[[mapView annotations] lastObject] animated:YES];


小智 5

我仔细阅读了API,最后我发现了问题:


如果指定的注释不在屏幕上,因此没有关联的注释视图,则此方法无效.

因此,您可以等待一段时间(例如,3秒),然后执行此操作.然后它工作.


use*_*509 5

调用selectAnnotationfrom 的问题- (void)mapViewDidFinishLoadingMap:(MKMapView *)mapView在于,顾名思义,此事件仅在MapView最初加载时触发,因此如果在MapView完成加载后添加注释,则无法触发注释的标注.

调用它的问题- (void)mapView:(MKMapView *)mapView didAddAnnotationViews:(NSArray *)views是,当selectAnnotation调用时,您的注释可能不在屏幕上,这会导致它无效.即使您在添加注释之前将MapView的区域居中到注释的坐标,设置MapView区域所需的轻微延迟也足以selectAnnotation在注释在屏幕上可见之前被调用,尤其是在您设置动画时setRegion.

有些人selectAnnotation在延迟之后打电话来解决这个问题:

-(void)mapView:(MKMapView *)mapView didAddAnnotationViews:(NSArray *)views {
    [self performSelector:@selector(selectLastAnnotation)
        withObject:nil afterDelay:1];
}

-(void)selectLastAnnotation {
    [myMapView selectAnnotation:
        [[myMapView annotations] lastObject] animated:YES];
}
Run Code Online (Sandbox Code Playgroud)

但即便如此,您可能会得到奇怪的结果,因为注释可能需要一秒多的时间才能显示在屏幕上,具体取决于各种因素,例如您之前的MapView区域与新区域之间的距离或您的Internet连接速度.

我决定进行调用,- (void)mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated因为它确保注释实际上在屏幕上(假设您将MapView的区域设置为注释的坐标),因为此事件 setRegion(及其动画)完成触发.但是,regionDidChangeAnimated只要MapView的区域发生变化,就会触发,包括当用户只是在地图周围移动时,您必须确保有条件正确识别何时是触发注释标注的正确时间.

我是这样做的:

MKPointAnnotation *myAnnotationWithCallout;

- (void)someMethod {
    MKPointAnnotation *myAnnotation = [[MKPointAnnotation alloc] init];
    [myAnnotation setCoordinate: someCoordinate];
    [myAnnotation setTitle: someTitle];

    MKCoordinateRegion someRegion =
       MKCoordinateRegionMakeWithDistance (someCoordinate, zoomLevel, zoomLevel);

    myAnnotationWithCallout = myAnnotation;
    [myMapView setRegion: someRegion animated: YES];
    [myMapView addAnnotation: myAnnotation];
}

- (void)mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated
{
    if (myAnnotationWithCallout)
    {
        [mapView selectAnnotation: myAnnotationWithCallout animated:YES];
        myAnnotationWithCallout = nil;
    }
}
Run Code Online (Sandbox Code Playgroud)

这样就可以确保您的注释在屏幕上selectAnnotation被调用,并且该if (myAnnotationWithCallout)部分确保除了该区域之外的任何区域设置- (void)someMethod都不会触发标注.