我正在MKMapView
使用通常的彩色图钉作为定位点。我希望能够在不触摸图钉的情况下显示标注。
我该怎么办?调用setSelected:YES
注释视图没有任何作用。我正在考虑模拟在别针上的触摸,但是我不确定该怎么做。
Answers:
但是有一个问题可以使benvolioT的解决方案起作用,代码
for (id<MKAnnotation> currentAnnotation in mapView.annotations) {
if ([currentAnnotation isEqual:annotationToSelect]) {
[mapView selectAnnotation:currentAnnotation animated:FALSE];
}
}
应该从调用- (void)mapViewDidFinishLoadingMap:(MKMapView *)mapView
,而在其他任何地方都不能调用。
的序列,其中的各种方法喜欢viewWillAppear
,viewDidAppear
的UIViewController
并且- (void)mapViewDidFinishLoadingMap:(MKMapView *)mapView
被称为是第一次地图被加载有一个特定的位置和后续次地图被显示以相同的位置之间不同。这有点棘手。
mapView:didAddAnnotationViews:
。这样可以确保地图视图已加载,注释视图也已放置并准备显示标注气泡。取决于连接速度,缓存系统,应用程序中断等,任何其他方式都行不通。
好的,这是解决此问题的方法。
要显示标注,请使用MKMapView
的selectAnnotation:animated
方法。
假设您要选择最后一个注释视图,可以将代码放在下面:
[mapView selectAnnotation:[[mapView annotations] lastObject] animated:YES];
在下面的代表中:
- (void)mapView:(MKMapView *)mapView didAddAnnotationViews:(NSArray *)views
{
//Here
[mapView selectAnnotation:[[mapView annotations] lastObject] animated:YES];
}
好的,要成功添加标注,您需要使用委托人的didAddAnnotationViews在添加所有注释视图之后调用selectAnnotation:animated:
- (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];
顾名思义,调用selectAnnotation
from的问题- (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];
}
但是即使那样,您也可能会得到奇怪的结果,因为注释可能要花费一秒钟以上的时间才能显示在屏幕上,具体取决于各种因素,例如以前的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;
}
}
这样一来,您的注解就可以在当前selectAnnotation
被显示在屏幕上,并且该if (myAnnotationWithCallout)
部件确保除- (void)someMethod
inone外的其他任何区域设置都不会触发标注。
我仔细阅读了API,最后发现了问题:
如果指定的注释不在屏幕上,因此没有关联的注释视图,则此方法无效。
因此,您可以等待一段时间(例如3秒),然后执行此操作。然后就可以了。
由于类似于benvolioT所示的代码,我怀疑系统中存在该代码,因此当我使用selectAnnotation:animation:方法时,它没有显示callOut,我猜测原因是因为它已被选择并且正在避免要求MapView使用注释标题和副标题在地图上重新绘制标注。
因此,解决方案就是先取消选择它,然后重新选择它。
例如:首先,我需要在Apple的touchMoved方法中执行此操作(即,如何拖动AnnotationView)以隐藏callOut。(仅使用annotation.canShowAnnotation = NO不能正常工作,因为我怀疑它需要重绘。deselectAnnotaiton会导致必要的操作。此外,仅取消选择并不能解决问题,callOut仅消失一次并立即被重画。这提示它已自动重新选择)。
annotationView.canShowAnnotation = NO;
[mapView deselectAnnotation:annotation animated:YES];
然后,仅在touchEnded方法中使用下面的代码并没有带回callOut(此时注释已由系统自动选择,并且可能永远不会重绘callOut):
annotationView.canShowAnnotation = YES;
[mapView selectAnnotation:annotation animated:YES];
解决方案是:
annotationView.canShowAnnotation = YES;
[mapView deselectAnnotation:annotation animated:YES];
[mapView selectAnnotation:annotation animated:YES];
这只是回购了callOut,大概是重新启动了mapView重绘callOut的过程。
严格来说,我应该检测注释是否为当前注释(选中,我知道是),以及callOut是否实际显示(我不知道),并决定相应地重绘它,这样会更好。但是,我还没有找到callOut检测方法,因此我自己在这个阶段就没有必要了。
重置注释也会将标注置于最前面。
[mapView removeAnnotation: currentMarker];
[mapView addAnnotation:currentMarker];