【问题标题】:Animate MKMapView camera heading transition动画 MKMapView 相机航向过渡
【发布时间】:2017-06-01 19:52:06
【问题描述】:

我想要实现的是当userTrackingMode为followWithHeading时mapView中的动画(地图如何旋转)。

问题是我不能在这里使用这种跟踪模式,因为我们根据不同的位置信息绘制了自己的蓝点,而不是 iOS 提供的。每次标题更新时,我都想设置 mapView 的摄像头标题值,但要设置动画以使其平滑。

目前我已经尝试过:

  1. setCamera: animated:这在标题频繁变化的情况下效果不佳。
  2. animateWithDuration:animations:completion: 这根本行不通。
  3. 我试过 CADisplayLink 就像下面的代码一样,但过渡还是不流畅。

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 秒设置一次相机,它不是动画。

有人能指出实现这一目标的正确方法吗?任何想法将不胜感激。

【问题讨论】:

  • 我也遇到了同样的问题,你找到解决办法了吗?提前致谢
  • 我们最终使用了 setCamera: animated: 方法。过渡在某种程度上是平稳的。我认为这取决于您获得位置更新的频率。

标签: ios mkmapview core-animation cadisplaylink


【解决方案1】:

我在使用 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
        }
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-03-08
    • 1970-01-01
    • 2014-02-22
    • 1970-01-01
    • 1970-01-01
    • 2012-09-30
    • 1970-01-01
    • 2017-09-22
    相关资源
    最近更新 更多