【问题标题】:setRegion: MKMapView becomes unresponsivesetRegion:MKMapView 变得无响应
【发布时间】:2017-02-10 13:31:58
【问题描述】:

我有一个MKMapView,上面有两个按钮:放大和缩小。

我注意到,当我使用它们时,在动画完成之前,我无法再捏地图进行缩放。

我的按钮连接到setRegion 的跨度比现在更小或更大。

我尝试将UIPinchGestureRecognizer 添加到我的地图以停止动画并允许捏合工作。我是这样做的:

我添加了一个Bool 变量,该变量通过点击按钮来保持地图当前是否处于动画状态。

func pinchRecognized() {
    if animating {
        var region = self.region
        region.span.latitudeDelta += 0.001
        setRegion(region, animated: false)
        animating = false
    }
}

我像这样覆盖 setRegion:

override func setRegion(_ region: MKCoordinateRegion, animated: Bool) {
    if (animated)
    {
        animating = true
        super.setRegion(region, animated: animated)

        perform(#selector(noLongerAnimating), with: nil, afterDelay: 1)
    }
    else
    {
        super.setRegion(region, animated: animated)
    }
}

func noLongerAnimating() {
    animating = false
}

这些在停止动画时起作用,但地图本身无法识别缩放以进行缩放,即使我这样做:

func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
    return true
}

我猜pinchRecognized 中的setRegion 会破坏它,但我不知道如何停止动画。

按要求,按钮代码,两个按钮都用这个方法,放大用0.5,缩小用2:

func zoomTo(delta: Double, animated: Bool) {
    var region = self.region
    var span = region.span

    span.latitudeDelta *= delta
    span.longitudeDelta *= delta
    if (span.latitudeDelta < 180 && span.longitudeDelta < 180)
    {
        region.span = span
        setRegion(region, animated: animated)
    }
}

编辑:我尝试在gestureRecognizer:shouldRecognizeSimultaneouslyWith: 中设置setRegion(停止动画的那个),但是在为地图设置动画时它不会被调用。

编辑:在尝试了@robinb 的建议后,我发现我的注释更新比我的地图本身更快,这表明该区域已设置,它只是等待某些东西以可视方式更新地图。

【问题讨论】:

  • 可以发一下你的按钮方法代码吗?
  • @CodeChanger 更新了问题
  • 重写 setRegion: function 的任何特殊原因?
  • @aman.sood 如果地图正在动画,则设置一个变量,该变量在动画开始之前设置,并在动画开始后延迟1秒。我这样做是为了知道视图是否在我的 pinchrecognized 中动画,以便我可以取消动画。
  • 好的。总而言之,您需要缩放和捏合才能毫不拖延地工作?如果是,请让我为您找到解决方案。

标签: ios swift


【解决方案1】:

手势识别器不会触发正在动画化的视图。将视图保存在 ViewController 的变量/数组中。使用本文中的代码执行动画:https://stackoverflow.com/a/13814789/3970581

这里是测试项目:https://github.com/DuncanMC/iOS-CAAnimation-group-demo

【讨论】:

  • 我认为这会起作用,但在手势识别器的地图上使用 setRegion 似乎并没有更新地图。单步执行代码不会显示任何错误,setRegion 会使用正确的值进行更新,只是不会更新区域。
【解决方案2】:

MapView 动画在启动时将 isUserInteractionEnabled 设置为 false,但是如果你想强制这样做,你可以继承 MKMapView 并覆盖 UIView 的 touchesBegan 方法来响应用户交互。在那里,您可以首先在没有动画的情况下调用 setCenter/setRegion(开始值或目标值)来中断/退出正在进行的动画并将 isUserInteractionEnabled 设置为 true。

MKMapView 使用 CATiledLayer,不幸的是,在中断时没有简单的方法来获取地图的区域和/或中心。 另一方面,我注意到虽然是私有的,但动画持续时间是恒定的,因此您可以在调用 touchesBegun 时使用 Timer 更好地猜测地图的区域

private var isAnimating: Bool = false

override func setRegion(_ region: MKCoordinateRegion, animated: Bool) {
   isAnimating = animated
   ...
}

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
    if isAnimating {
       isAnimating = false
       let region = // Destination region or the approximate region where the animation reached at this moment (although this is a nightmare todo)
       setRegion(region: region, animated: false) // or use setCenter
       isUserInteractionEnabled = true 
    }
}

【讨论】:

  • 这给出了相同的结果,地图使用 setRegion(),它打破了你刚刚开始的当前夹点。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-05-13
  • 1970-01-01
  • 1970-01-01
  • 2022-10-25
  • 1970-01-01
  • 2019-04-08
  • 2019-12-03
相关资源
最近更新 更多