这个问题的由来可谓久矣,困扰我的时间之长,也可谓不短矣,已经有将近一个月。
事情是这样的:
我们的地图界面有个新需求,做一个可以一直动的动图。用专业的话来说,就是一个动态的 annotationView ,并且它还要一直改变位置。
情形是:五朵云,四只鸟,一起飞,从地图的左边飞到右边,并且,飞过去之后,还要再从左边再飞出来。云的速度和鸟的速度是不一样的,但是大概是那个意思,不会太快,也不会太慢,但也不会那么整齐显得不真实。
最后一切都好说,然而在显示的时候出问题了:
我用的 CADisplayLink ,这样可以确保最流畅的动画效果。但是问题来了,刷新 animatedAnnotationView 该怎么做?
我用了 showAnnotations 这个方法。就是之前已经 addAnnotations 添加过了,但是在更新了 array 中 animatedAnnotation 的位置后,要再在地图上显示出来。
可行的。
但是等等……
地图为什么会突然放大一点点?而且是偶尔的?
因为这个:
屏幕快照 2018-03-09 17.38.21.png
这个方法会以当前的 annotationView 为中心,如果只有一个的话;
但是多个的话,就会出现那个跳跳的 bug 了。
而且!!
我点击 POI (也是 annotationView ,不过不是动态的)之后,本来设置的一些操作,比如地图以当前点击的 POI 为中心,不能运行了!
更糟糕的是,点击定位按钮的逻辑处理也不行了……
这就不行了。因为定位要显示用户当前的地理位置,这个功能不能用,是断然不行的。
后来我就想了一想,那就把调用 showAnnotation 的这个方法去掉试试看。
那些莫名的 bug 都消失了,开心哪。
嘿嘿,竟然还是可以跑起来(就是飞起来,从左到右飞动着……);
然而,飞了一段距离之后,怎么,怎么卡起来了?卡卡卡的。
但是,用手指在地图上点一下,或者随便划那么一下,就不卡了。
我想到了 runloop 。可怕的想法。
我在想,是不是因为 CADisplayLink 添加的 runloop 和地图渲染的不一致?
调为一致,不行。
我在想,是不是因为没有主线程调用?用主线程,不行。
我在想,是不是因为 CADisplayLink 这个不行?
换 GCD Timer ,还是不行!!!
一个多月了,这个问题像大山一样压着我的神经,因为这个 bug 的存在,让整个界面不完美了,这种感觉是非常非常煎熬的。
人家安卓的只用调用一个 runOnDrawFrame 的方法,一切完美!然而 iOS 没有!我甚至还开了一工单,准备向高德的 SDK 开发人员问问情况。
一边开着窗口,一边看着手机屏幕,飞鸟和飞云还是卡卡的,卡卡的……
然而我的调用方法是一直在走的,这说明:
实际的位置已经在变了,但是刷新不及时;
刷新不及时,说明帧数变低了;
帧数变低了??????
帧数变低了?
那怎么办?这明明是 SDK 内部实现的节约电量的优化啊。
我就强制刷新!!!
搜索一大通,试了各种招式,最好用的,最有用的,
全部都没有用。
唉。
我就在谷歌搜索的“高德地图 SDK”后面添加了一个“帧数”。
果然!!!!
mapView 开启了一个叫做 isAllowDecreaseFrame 的属性,这玩意默认是设置为 YES 的。无耻。——不不不,是我无知了。
赶紧设置为 NO ,再试试。
一切完美。
谨为记,因为这个坑实在是大极了。
三月九日 1805
网友评论