如何在不触摸引脚的情况下触发MKAnnotationView的标注视图?
我MKMapView
使用通常的彩色引脚作为位置点的MKMapView
。 我希望能够在不触及引脚的情况下显示标注。
我该怎么做? 在annotationview上调用setSelected:YES
什么都不做。 我正在考虑模拟触摸,但我不知道如何去做。
但有一个获得benvolioT解决scheme的工作,代码
for (id<MKAnnotation> currentAnnotation in mapView.annotations) { if ([currentAnnotation isEqual:annotationToSelect]) { [mapView selectAnnotation:currentAnnotation animated:FALSE]; } }
应该从- (void)mapViewDidFinishLoadingMap:(MKMapView *)mapView
和其他地方调用。
调用UIViewController
和- (void)mapViewDidFinishLoadingMap:(MKMapView *)mapView
这样的各种方法(如viewWillAppear
, viewDidAppear
- (void)mapViewDidFinishLoadingMap:(MKMapView *)mapView
在第一次加载地图的时候和第二次地图显示的时间是不同的与相同的位置。 这有点棘手。
好的,这是解决这个问题的方法。
要显示标注,请使用MKMapView
的selectAnnotation:animated
方法。
假设你想要select最后的注解视图,你可以把下面的代码:
[mapView selectAnnotation:[[mapView annotations] lastObject] animated:YES];
在下面的代表中:
- (void)mapView:(MKMapView *)mapView didAddAnnotationViews:(NSArray *)views { //Here [mapView selectAnnotation:[[mapView annotations] lastObject] animated:YES]; }
好的,要成功添加标注,您需要调用selectAnnotation:在添加了所有注释视图后使用委托的didAddAnnotationViews进行animation处理:
- (void)mapView:(MKMapView *)mapView didAddAnnotationViews:(NSArray *)views{ for (id<MKAnnotation> currentAnnotation in mapView.annotations) { if ([currentAnnotation isEqual: annotationToSelect]) { [mapView selectAnnotation:currentAnnotation animated:YES]; } } }
在尝试了各种线程的答案后,我终于想出了这个。 它工作非常可靠,我还没有看到它失败:
- (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]; }); } } }
该块用于稍微延迟,因为没有它可能无法正确显示标注。
这对我不起作用。 我怀疑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]; } }
注意,这需要实现- (BOOL)isEqual:(id)anObject
用于实现MKAnnotation协议的类。
如果你只是想打开你添加的最后一个注释的标注,试试这个,为我工作。
[mapView selectAnnotation:[[mapView annotations] lastObject] animated:YES];
我仔细阅读API,最后发现问题:
如果指定的注释不在屏幕上,因此没有关联的注释视图,则此方法不起作用。
所以你可以等一段时间(例如3秒)然后执行这个动作。 然后它工作。
从- (void)mapViewDidFinishLoadingMap:(MKMapView *)mapView
调用selectAnnotation
的问题是,正如其名称所暗示的,这个事件只会在您的MapView初始加载后才触发,所以如果您触发了注释的标注在MapView完成加载后添加它。
从- (void)mapView:(MKMapView *)mapView didAddAnnotationViews:(NSArray *)views
调用它的问题是,当selectAnnotation
调用selectAnnotation
时,您的注释可能不会在屏幕上,这将导致它无效。 即使在添加注释之前将MapView的区域居中于注释坐标,设置MapView区域所需的轻微延迟也足以使注释在屏幕上可见之前调用selectAnnotation
,特别是在设置了setRegion
animationsetRegion
。
有些人通过延迟调用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]; }
但即使如此,您可能会得到奇怪的结果,因为注释可能需要一秒多的时间才能显示在屏幕上,具体取决于各种因素,例如之前的MapView地区与新build的地图之间的距离或Internet连接速度。
我决定从- (void)mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated
因为它确保注释实际上是在屏幕上(假设您将MapView的区域设置为注释的坐标),因为此事件在 setRegion
(及其animation)完成后触发。 但是,只要MapView的区域发生变化,就会触发regionDidChangeAnimated
,包括用户只是围绕地图移动,因此您必须确保有一个条件来正确识别什么时候触发注释的标注。
以下是我如何做到的:
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; } }
这样,您的注释保证在屏幕上的时候selectAnnotation
被调用,而if (myAnnotationWithCallout)
部分确保没有区域设置除了- (void)someMethod
将触发标注。
由于像benvolioT所示的代码,我怀疑系统中存在的东西,当我使用selectAnnotation:animation:方法,它没有显示callOut,我猜想,原因是因为它已经被选中,它是避免要求MapView使用注释标题和子标题重绘地图上的callOut。
所以,解决方法就是先取消select并重新select它。
例如:首先,我需要在Apple的touchMoved方法(即如何拖动AnnotationView)中隐藏callOut。 (简单地使用annotation.canShowAnnotation = NO是不行的,因为我怀疑它需要重绘,取消selectAnnotaiton会导致必要的操作,而且,单独取消select并不能解决问题,callOut只消失一次,直接重绘。是自动重新select的提示)。
annotationView.canShowAnnotation = NO; [mapView deselectAnnotation:annotation animated:YES];
然后,在touchEnded方法中简单地使用下面的代码并没有带回callOut(当时系统已经自动select了注解,并且可能是callOut的重画不会出现):
annotationView.canShowAnnotation = YES; [mapView selectAnnotation:annotation animated:YES];
解决scheme是:
annotationView.canShowAnnotation = YES; [mapView deselectAnnotation:annotation animated:YES]; [mapView selectAnnotation:annotation animated:YES];
这只是买了callOut,大概是重新启动了mapView重绘callOut的过程。
严格地说,我应该检测注释是否是当前注释(select,我知道它是否)以及callOut是否实际显示或不显示(我不知道)并决定相应地重绘它,会更好。 然而,我现在还没有findcallOut检测方法,而现在我自己只是在这个阶段不需要这么做。
史蒂夫·史的回应清楚地告诉我,selectAnnotation必须从mapViewDidFinishLoadingMap方法中调用。 不幸的是我不能投票,但我想在这里表示感谢。
重置注释也会使标注前面。
[mapView removeAnnotation: currentMarker]; [mapView addAnnotation:currentMarker];
只需添加[mapView selectAnnotation:point animated:YES];