简体   繁体   English

动画MKMapView摄像头标题过渡

[英]Animate MKMapView camera heading transition

What I want to achieve is like the animation (how the map rotates) in mapView when userTrackingMode is followWithHeading. 当userTrackingMode为followWithHeading时,我想要实现的就像mapView中的动画(地图如何旋转)。

The thing is I can't use this tracking mode here because we draw our own blue dot based on the different location information instead of the one provided by iOS. 问题是我不能在这里使用这种跟踪模式,因为我们根据不同的位置信息绘制我们自己的蓝点,而不是iOS提供的蓝点。 Every time the heading get updated, I want to set the mapView's camera heading value, but animated to make it smooth. 每次标题更新时,我都要设置mapView的摄像头标题值,但要设置动画以使其平滑。

Currently I've tried: 目前我已经尝试过:

  1. setCamera: animated: This doesn't work well when the heading changes frequently. setCamera: animated:当标题频繁更改时,这不起作用。
  2. animateWithDuration:animations:completion: This doesn't work at all. animateWithDuration:animations:completion:这根本不起作用。
  3. I tried CADisplayLink like the code below, still the transition is not smooth. 我尝试了CADisplayLink,如下面的代码,仍然过渡不顺利。

CADisplayLink *timer = [CADisplayLink displayLinkWithTarget:self selector:@selector(updateHeading)]; timer.frameInterval = 5; [timer addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode]; [timer addToRunLoop:[NSRunLoop mainRunLoop] forMode:UITrackingRunLoopMode];

and in the updateHeading method I just set the mapView's camera to the current heading self.camera.heading = newHeading.trueHeading; updateHeading方法中,我只是将mapView的摄像头设置为当前标题self.camera.heading = newHeading.trueHeading;

I guess this doesn't work because I am only setting the camera every 5/60 seconds here, it's not animating. 我想这不起作用,因为我只在这里每隔5/60秒设置一次相机,这不是动画。

Can someone point out the correct way to achieve this? 有人能指出实现这一目标的正确方法吗? Any thought will be appreciated. 任何想法将不胜感激。

I've had some luck using CADisplayLink, if you move a larger amount like 170 degrees it is a bit slower but in general it works smoothly. 我有一些运气使用CADisplayLink,如果你移动一个更大的数量,如170度,它有点慢,但总的来说它运作顺利。 I'm going to look at adding an easing function to it but for the time being it's the smoothest route I've seen. 我将考虑为它添加一个缓动功能,但暂时它是我见过的最平滑的路线。

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
        }
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM