热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

MapKit(MKMapView):zPosition在iOS11上不再起作用

如何解决《MapKit(MKMapView):zPosition在iOS11上不再起作用》经验,为你挑选了2个好方法。

iOS11zPosition停止的annotationView.layer工作.每次地图区域发生变化.

在此输入图像描述

原始解决方案没有运气:layer.zPosition = X;

没有运气bringViewToFront/ SendViewToBack方法

Xcode 8.3/9

更新(解决方案感谢Elias Aalto):

创建MKAnnotationView时:

annotationView.layer.zPosition = 50;
if (IS_OS_11_OR_LATER) {
    annotationView.layer.name = @"50";
    [annotationView.layer addObserver:MeLikeSingleton forKeyPath:@"zPosition" options:0 context:NULL];

}

在MeLikeSingleton或你在那里的任何观察者对象:

- (void)observeValueForKeyPath:(NSString *)keyPath
                         ofObject:(id)object
                           change:(NSDictionary *)change
                          context:(void *)context {

       if (IS_OS_11_OR_LATER) {

           if ([keyPath isEqualToString:@"zPosition"]) {
               CALayer *layer = object;
               int zPosition = FLT_MAX;
               if (layer.name) {
                   zPosition = layer.name.intValue;
               }
               layer.zPosition = zPosition;
               //DDLogInfo(@"Name:%@",layer.name);
           }

       } 
}

此解决方案使用layer.name值来跟踪zOrder.如果您有多个级别的zPosition(用户位置,群集,引脚,标注);)

不用于循环,只有KVO

我使用了一个Singleton Object来观察图层值的变化.如果您在整个应用程序中使用了多个MKMapView.

它是如何在IOS11之前工作的

..是用的

- (void)mapView:(MKMapView *)mapView didAddAnnotationViews:(NSArray *)views

并在此处设置zPosition.

..但是(对于我们中的一些人,仍然是dunny为什么)在iOS11中不再起作用了!



1> Elias Aalto..:

zPosition 确实有效,只是MKMapView基于有点破碎和无用的MKFeatureDisplayPriority在内部覆盖它.如果你只需要一些注释来坚持"其他一切",那么你可以使用KVO 干净地完成这项工作.只需将一个观察者添加到注释视图的图层的zPosition中,并在MKMapView试图摆弄它时覆盖它.

(请原谅我的ObjC)

添加观察者:

        [self.annotationView.layer addObserver:self forKeyPath:@"zPosition" options:0 context:nil];

否决MKMapView

 - (void)observeValueForKeyPath:(NSString *)keyPath
                  ofObject:(id)object
                    change:(NSDictionary *)change
                   context:(void *)context
{
    if(object == self.annotationView.layer)
    {
        self.annotationView.layer.zPosition = FLT_MAX;
    }
}

利润



2> bteapot..:

我们可以完全忽略MKMapView修改MKAnnotationView层的尝试zPosition。由于MKAnnotationView使用standard CALayer作为其层而不是某些私有类,因此我们可以对其进行子类化并覆盖其zPosition。要进行实际设置,zPosition我们可以提供我们自己的访问器。

它的工作速度比KVO快得多。

class ResistantLayer: CALayer {

    override var zPosition: CGFloat {
        get { return super.zPosition }
        set {}
    }
    var resistantZPosition: CGFloat {
        get { return super.zPosition }
        set { super.zPosition = newValue }
    }
}

class ResistantAnnotationView: MKAnnotationView {

    override class var layerClass: AnyClass {
        return ResistantLayer.self
    }
    var resistantLayer: ResistantLayer {
        return self.layer as! ResistantLayer
    }
}

更新:

点击重叠的注释时,我有一个非常优雅的方法可以选择最上面的注释视图。

class MyMapView: MKMapView {

    override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {

        // annotation views whose bounds contains touch point, sorted by visibility order
        let views =
            self.annotations(in: self.visibleMapRect)
                .flatMap { $0 as? MKAnnotation }
                .flatMap { self.view(for: $0) }
                .filter { $0.bounds.contains(self.convert(point, to: $0)) }
                .sorted(by: {
                    view0, view1 in

                    let layer0  = view0.layer
                    let layer1  = view1.layer
                    let z0      = layer0.zPosition
                    let z1      = layer1.zPosition

                    if z0 == z1 {
                        if  let subviews = view0.superview?.subviews,
                            let index0 = subviews.index(where: { $0 === view0 }),
                            let index1 = subviews.index(where: { $0 === view1 })
                        {
                            return index0 > index1
                        } else {
                            return false
                        }
                    } else {
                        return z0 > z1
                    }
                })

        // disable every annotation view except topmost one
        for item in views.enumerated() {
            if item.offset > 0 {
                item.element.isEnabled = false
            }
        }

        // re-enable annotation views after some time
        DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
            for item in views.enumerated() {
                if item.offset > 0 {
                    item.element.isEnabled = true
                }
            }
        }

        // ok, let the map view handle tap
        return super.hitTest(point, with: event)
    }
}


推荐阅读
  • 在Android开发中,使用Picasso库可以实现对网络图片的等比例缩放。本文介绍了使用Picasso库进行图片缩放的方法,并提供了具体的代码实现。通过获取图片的宽高,计算目标宽度和高度,并创建新图实现等比例缩放。 ... [详细]
  • Java太阳系小游戏分析和源码详解
    本文介绍了一个基于Java的太阳系小游戏的分析和源码详解。通过对面向对象的知识的学习和实践,作者实现了太阳系各行星绕太阳转的效果。文章详细介绍了游戏的设计思路和源码结构,包括工具类、常量、图片加载、面板等。通过这个小游戏的制作,读者可以巩固和应用所学的知识,如类的继承、方法的重载与重写、多态和封装等。 ... [详细]
  • Iamtryingtomakeaclassthatwillreadatextfileofnamesintoanarray,thenreturnthatarra ... [详细]
  • Java容器中的compareto方法排序原理解析
    本文从源码解析Java容器中的compareto方法的排序原理,讲解了在使用数组存储数据时的限制以及存储效率的问题。同时提到了Redis的五大数据结构和list、set等知识点,回忆了作者大学时代的Java学习经历。文章以作者做的思维导图作为目录,展示了整个讲解过程。 ... [详细]
  • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
  • 深入理解Kafka服务端请求队列中请求的处理
    本文深入分析了Kafka服务端请求队列中请求的处理过程,详细介绍了请求的封装和放入请求队列的过程,以及处理请求的线程池的创建和容量设置。通过场景分析、图示说明和源码分析,帮助读者更好地理解Kafka服务端的工作原理。 ... [详细]
  • 重入锁(ReentrantLock)学习及实现原理
    本文介绍了重入锁(ReentrantLock)的学习及实现原理。在学习synchronized的基础上,重入锁提供了更多的灵活性和功能。文章详细介绍了重入锁的特性、使用方法和实现原理,并提供了类图和测试代码供读者参考。重入锁支持重入和公平与非公平两种实现方式,通过对比和分析,读者可以更好地理解和应用重入锁。 ... [详细]
  • 本文介绍了闭包的定义和运转机制,重点解释了闭包如何能够接触外部函数的作用域中的变量。通过词法作用域的查找规则,闭包可以访问外部函数的作用域。同时还提到了闭包的作用和影响。 ... [详细]
  • HDU 2372 El Dorado(DP)的最长上升子序列长度求解方法
    本文介绍了解决HDU 2372 El Dorado问题的一种动态规划方法,通过循环k的方式求解最长上升子序列的长度。具体实现过程包括初始化dp数组、读取数列、计算最长上升子序列长度等步骤。 ... [详细]
  • 本文主要解析了Open judge C16H问题中涉及到的Magical Balls的快速幂和逆元算法,并给出了问题的解析和解决方法。详细介绍了问题的背景和规则,并给出了相应的算法解析和实现步骤。通过本文的解析,读者可以更好地理解和解决Open judge C16H问题中的Magical Balls部分。 ... [详细]
  • Spring特性实现接口多类的动态调用详解
    本文详细介绍了如何使用Spring特性实现接口多类的动态调用。通过对Spring IoC容器的基础类BeanFactory和ApplicationContext的介绍,以及getBeansOfType方法的应用,解决了在实际工作中遇到的接口及多个实现类的问题。同时,文章还提到了SPI使用的不便之处,并介绍了借助ApplicationContext实现需求的方法。阅读本文,你将了解到Spring特性的实现原理和实际应用方式。 ... [详细]
  • 本文详细介绍了在ASP.NET中获取插入记录的ID的几种方法,包括使用SCOPE_IDENTITY()和IDENT_CURRENT()函数,以及通过ExecuteReader方法执行SQL语句获取ID的步骤。同时,还提供了使用这些方法的示例代码和注意事项。对于需要获取表中最后一个插入操作所产生的ID或马上使用刚插入的新记录ID的开发者来说,本文提供了一些有用的技巧和建议。 ... [详细]
  • Python正则表达式学习记录及常用方法
    本文记录了学习Python正则表达式的过程,介绍了re模块的常用方法re.search,并解释了rawstring的作用。正则表达式是一种方便检查字符串匹配模式的工具,通过本文的学习可以掌握Python中使用正则表达式的基本方法。 ... [详细]
  • 本文讨论了一个数列求和问题,该数列按照一定规律生成。通过观察数列的规律,我们可以得出求解该问题的算法。具体算法为计算前n项i*f[i]的和,其中f[i]表示数列中有i个数字。根据参考的思路,我们可以将算法的时间复杂度控制在O(n),即计算到5e5即可满足1e9的要求。 ... [详细]
  • 李逍遥寻找仙药的迷阵之旅
    本文讲述了少年李逍遥为了救治婶婶的病情,前往仙灵岛寻找仙药的故事。他需要穿越一个由M×N个方格组成的迷阵,有些方格内有怪物,有些方格是安全的。李逍遥需要避开有怪物的方格,并经过最少的方格,找到仙药。在寻找的过程中,他还会遇到神秘人物。本文提供了一个迷阵样例及李逍遥找到仙药的路线。 ... [详细]
author-avatar
林斯诺_SNOW
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有