You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Swift中Apple Map的MKOverlayRenderer图片缩放旋转异常求助

解决Apple Map叠加图片缩放超过2.0时旋转导致的损坏问题

问题出在坐标变换顺序错误以及旋转原点未设置为图片中心,当缩放级别较高时,CGContext的坐标映射会出现偏差,导致图片绘制超出上下文可视区域或像素错位,最终表现为图片损坏。

修复步骤

  • 先保存当前上下文状态,避免后续变换影响其他绘制操作
  • 将上下文平移至图片中心位置,确保旋转围绕图片中心进行
  • 执行旋转操作后平移回原位置,修正坐标系
  • 处理UIKit与Core Graphics的Y轴方向差异
  • 绘制图片时确保上下文缩放因子与图片匹配

修改后的完整代码

class IndoorInfoOverlay: NSObject, MKOverlay {
    let coordinate: CLLocationCoordinate2D
    let boundingMapRect: MKMapRect

    init(indoorInfo: IndoorInfo) {
      boundingMapRect = indoorInfo.overlayBoundingMapRect
      coordinate = indoorInfo.midCoordinate
    }
}

class IndoorInfoOverlayView: MKOverlayRenderer {
  var overlayImage: UIImage
  var parent: IndoorMapView

  init(overlay: MKOverlay, overlayImage: UIImage, _ parent: IndoorMapView) {
      self.overlayImage = overlayImage
      self.parent = parent
      super.init(overlay: overlay)
  }

  override func draw(_ mapRect: MKMapRect, zoomScale: MKZoomScale, in context: CGContext) {
    guard let imageReference = overlayImage.cgImage else { return }
    let bearing = degreesToRadians(360 - (Double(self.parent.floorData?.FLOOR_BEARING ?? 0)))
    let rect = self.rect(for: overlay.boundingMapRect)
    
    // 保存上下文初始状态
    context.saveGState()
    
    // 平移到图片中心,围绕中心旋转后再平移回原位置
    let center = CGPoint(x: rect.midX, y: rect.midY)
    context.translateBy(x: center.x, y: center.y)
    context.rotate(by: CGFloat(bearing))
    context.translateBy(x: -center.x, y: -center.y)
    
    // 处理UIKit与Core Graphics的Y轴翻转
    context.scaleBy(x: 1.0, y: -1.0)
    context.translateBy(x: 0.0, y: -rect.size.height)
    
    // 绘制图片
    let imageRect = CGRect(origin: .zero, size: rect.size)
    context.draw(imageReference, in: imageRect, byTiling: false)
    
    // 恢复上下文状态
    context.restoreGState()
  }
                               
  private func degreesToRadians(_ x: Double) -> Double {
    return Double.pi * x / 180.0
  }
}

关键说明

  • 旋转原点修正:通过先平移到图片中心再旋转,避免旋转后图片位置偏移,确保高缩放级别下图片始终在正确的地图区域内
  • 上下文状态隔离:用saveGState()和restoreGState()隔离当前绘制的变换操作,不会干扰地图其他元素的渲染
  • 坐标系逻辑调整:重新安排变换顺序,先处理旋转再处理Y轴翻转,保证坐标计算逻辑正确,避免像素错位

内容的提问来源于stack exchange,提问作者user2805987

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 17:15:38