当userTrackingMode为followWithHeading时,我想要实现的是mapView中的动画(地图如何旋转)。
事情是我不能在这里使用这种跟踪模式,因为我们根据不同的位置信息而不是iOS提供的位置信息绘制我们自己的蓝点。每次标题更新时,我都要设置mapView的摄像头标题值,但要设置动画以使其平滑。
目前我已尝试过:
setCamera: animated:
当标题经常更改时,这不会很好。animateWithDuration:animations:completion:
这根本不起作用。 CADisplayLink *timer = [CADisplayLink displayLinkWithTarget:self selector:@selector(updateHeading)];
timer.frameInterval = 5;
[timer addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];
[timer addToRunLoop:[NSRunLoop mainRunLoop] forMode:UITrackingRunLoopMode];
在updateHeading
方法中,我只是将mapView的相机设置为当前标题self.camera.heading = newHeading.trueHeading;
我想这不起作用,因为我每隔5/60秒只设置一次相机,这不是动画。
有人能指出实现这个目的的正确方法吗?任何想法都将受到赞赏。
答案 0 :(得分:0)
使用CADisplayLink时我有些运气,如果您移动较大的角度(例如170度),则速度会稍慢一些,但总体来说效果会很好。我将考虑在其中添加缓动功能,但是暂时这是我所见过的最平滑的路线。
private var headingDisplayLink: CADisplayLink?
private var desiredHeading: Double = 0
func locationManager(didUpdateHeading newHeading: CLHeading) {
self.updateHeading(to: newHeading.trueHeading)
}
private func updateHeading(to heading: Double) {
self.desiredHeading = heading.rounded()
if self.headingDisplayLink == nil {
self.headingDisplayLink = CADisplayLink(target: self, selector: #selector(self.headingDisplayLinkUpdate(link:)))
self.headingDisplayLinkUpdate(link: self.headingDisplayLink!)
self.headingDisplayLink?.add(to: RunLoop.main, forMode: .defaultRunLoopMode)
}
}
@objc private func headingDisplayLinkUpdate(link: CADisplayLink) {
if let camera = self.mapView?.camera.copy() as? MKMapCamera {
var delta: Double = self.desiredHeading > camera.heading ? 1 : -1
let difference = fabs(camera.heading - self.desiredHeading)
if difference > 180 {
delta *= -1
}
camera.heading += delta
self.mapView?.setCamera(camera, animated: false)
if camera.heading.rounded() == self.desiredHeading {
self.headingDisplayLink?.invalidate()
self.headingDisplayLink = nil
}
}
}