我需要将当前用户注释(蓝点)绘制在所有其他注释的顶部。现在它被画在其他注解的下面,然后被隐藏起来。我想调整这个注释视图的z-index(蓝点)把它放到最上面,有人知道怎么做吗?
更新:我现在可以获得MKUserLocationView的句柄,但我如何把它向前推进呢?
- (void) mapView:(MKMapView *)aMapView didAddAnnotationViews:(NSArray *)views {
for (MKAnnotationView *view in views) {
if ([[view annotation] isKindOfClass:[MKUserLocation class]]) {
// How do I bring this view to the front of all other annotations?
// [???? bringSubviewToFront:????];
}
}
}
在Paul Tiarks的帮助下,使用下面列出的代码最终使其工作。我遇到的问题是,MKUserLocation注释在其他注释之前首先被添加到地图中,所以当您添加其他注释时,它们的顺序似乎是随机的,并且仍然会在MKUserLocation注释的顶部结束。为了解决这个问题,我必须将所有其他注释移动到后面,以及将MKUserLocation注释移动到前面。
- (void) mapView:(MKMapView *)aMapView didAddAnnotationViews:(NSArray *)views
{
for (MKAnnotationView *view in views)
{
if ([[view annotation] isKindOfClass:[MKUserLocation class]])
{
[[view superview] bringSubviewToFront:view];
}
else
{
[[view superview] sendSubviewToBack:view];
}
}
}
更新:您可能需要添加下面的代码,以确保当将蓝点滚动到地图的可视区域时,它绘制在顶部。
- (void)mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated
{
for (NSObject *annotation in [mapView annotations])
{
if ([annotation isKindOfClass:[MKUserLocation class]])
{
NSLog(@"Bring blue location dot to front");
MKAnnotationView *view = [mapView viewForAnnotation:(MKUserLocation *)annotation];
[[view superview] bringSubviewToFront:view];
}
}
}
另一个解决方案:设置注释视图层的zPosition (annotationView.layer.zPosition
) in:
- (void)mapView:(MKMapView *)mapView didAddAnnotationViews:(NSArray *)views;
这个帖子的官方答案是错误的…使用zPosition确实是最好的方法和最快的使用regionDidChangeAnimated…
否则,map上的许多注释将对性能造成很大影响(因为每次更改帧都会重新扫描所有注释)。我一直在测试它……
所以当创建注释的视图(或在didAddAnnotationViews)集时:self.layer.zPosition = -1;
,正如你所指出的:这使得引脚盖标注从其他引脚- yuf Dec 5 '13 at 20:25
。注释视图将出现在其他引脚的下方。
要修复,只需在有选择
时将zPosition重新设置为0即可。-(void) mapView:(MKMapView*)mapView didSelectAnnotationView:(MKAnnotationView*)view {
if ([view isKindOfClass:[MyCustomAnnotationView class]])
view.layer.zPosition = 0;
...
}
-(void) mapView:(MKMapView*)mapView didDeselectAnnotationView:(MKAnnotationView*)view {
if ([view isKindOfClass:[MyCustomAnnotationView class]])
view.layer.zPosition = -1;
...
}
iOS 14更新
我知道这是一个老帖子,但是这个问题仍然适用,当你在你最喜欢的搜索引擎中输入它时,你会在这里结束。
从iOS 14开始,Apple为MKAnnotationView
引入了zPriority
属性。您可以使用它为使用预定义常量或浮点数的注释设置z-index。此外,Apple最终使我们能够自己创建用户位置视图,并提供MKUserLocationView
作为MKAnnotationView
的子类。
来自MKUserLocationView
的文档:
如果您想指定额外的配置,如
zPriority
,直接创建这个注释视图。要显示注释视图,返回mapView(_:viewFor:)
的实例
下面的代码片段显示了如何做到这一点(将代码添加到MKMapViewDelegate
中):
func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
// Alter the MKUserLocationView (iOS 14+)
if #available(iOS 14.0, *), annotation is MKUserLocation {
// Try to reuse the existing view that we create below
let reuseIdentifier = "userLocation"
if let existingView = mapView.dequeueReusableAnnotationView(withIdentifier: reuseIdentifier) {
return existingView
}
let view = MKUserLocationView(annotation: annotation, reuseIdentifier: reuseIdentifier)
view.zPriority = .max // Show user location above other annotations
view.isEnabled = false // Ignore touch events and do not show callout
return view
}
// Create views for other annotations or return nil to use the default representation
return nil
}
注意,默认情况下,用户位置注释在点击它时会显示一个标注。现在用户位置覆盖了其他注释,您可能想要禁用它,这可以在代码中通过将.isEnabled
设置为false
来实现。
使用.layer.anchorPointZ
属性。
的例子:
func mapView(_ mapView: MKMapView, didAdd views: [MKAnnotationView]) {
views.forEach {
if let _ = $0.annotation as? MKUserLocation {
$0.layer.anchorPointZ = 0
} else {
$0.layer.anchorPointZ = 1
}
}
}
这里有参考https://developer.apple.com/documentation/quartzcore/calayer/1410796-anchorpointz
尝试,获得对用户位置注释的引用(可能在mapView: didAddAnnotationViews:
中),然后在添加所有注释后将该视图带到mapView的前面。
Swift 3:
internal func mapView(_ mapView: MKMapView, didAdd views: [MKAnnotationView]) {
for annotationView in views {
if annotationView.annotation is MKUserLocation {
annotationView.bringSubview(toFront: view)
return
}
annotationView.sendSubview(toBack: view)
}
}
这里有一种使用谓词的方法。我觉得应该快一点
NSPredicate *userLocationPredicate = [NSPredicate predicateWithFormat:@"class == %@", [MKUserLocation class]];
NSArray* userLocation = [[self.mapView annotations] filteredArrayUsingPredicate:userLocationPredicate];
if([userLocation count]) {
NSLog(@"Bring blue location dot to front");
MKAnnotationView *view = [self.mapView viewForAnnotation:(MKUserLocation *)[userLocation objectAtIndex:0]];
[[view superview] bringSubviewToFront:view];
}
Using Underscore.m
_.array(mapView.annotations).
filter(^ BOOL (id<MKAnnotation> annotation) { return [annotation
isKindOfClass:[MKUserLocation class]]; })
.each(^ (id<MKAnnotation> annotation) { [[[mapView
viewForAnnotation:annotation] superview] bringSubviewToFront:[mapView
viewForAnnotation:annotation]]; });