在iOS中创建自定义地图功能

时间:2018-01-03 14:14:50

标签: ios uibutton mkmapview

Image of map

我想创建一个任何特定区域的示例地图,用户可以在其中点按任何区域,区域颜色将变为橙色。

为此,我在图像顶部添加了一些按钮,但它不能提供准确的结果。

请分享您的评论。

1 个答案:

答案 0 :(得分:1)

您可以使用CAShapeLayer。在此示例中,我检查触摸位置是否在特定图层内,然后检查触摸位置是否在此图层的路径内。

import UIKit

class ViewController: UIViewController {
  private let step = 50
  private lazy var rectSize = CGSize(width: step, height: step)
  private struct MapSize { let width: Int; let height: Int }
  private let mapCanvas = UIView()

  override func viewDidLoad() {
    super.viewDidLoad()

    generateMap(withSize: MapSize(width: 6, height: 6))

    view.addSubview(mapCanvas)
    mapCanvas.translatesAutoresizingMaskIntoConstraints = false
    NSLayoutConstraint.activate([
      view.leadingAnchor.constraint(equalTo: mapCanvas.leadingAnchor),
      view.trailingAnchor.constraint(equalTo: mapCanvas.trailingAnchor),
      view.topAnchor.constraint(equalTo: mapCanvas.topAnchor, constant: -200),
      mapCanvas.heightAnchor.constraint(equalToConstant: 300)
      ])

  }

  private func generateMap(withSize size: MapSize) {
    for x in 0..<size.width {
      for y in 0..<size.height {
        let layer = CAShapeLayer()
        layer.frame = CGRect(origin: CGPoint(x: x * step, y: y * step), size: rectSize)
        layer.path = createPath().cgPath
        layer.fillColor = UIColor.cyan.cgColor
        layer.borderWidth = 1
        layer.borderColor = UIColor.black.cgColor
        mapCanvas.layer.addSublayer(layer)
      }
    }
  }

  private func createPath() -> UIBezierPath {
    let rectangle = UIBezierPath()
    rectangle.move(to: CGPoint(x: 0, y: 0))
    rectangle.addLine(to: CGPoint(x: 0, y: step))
    rectangle.addLine(to: CGPoint(x: step, y: step))
    rectangle.addLine(to: CGPoint(x: step, y: 0))
    rectangle.close()
    return rectangle
  }

  override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
    guard let touch = touches.first, let sublayers = mapCanvas.layer.sublayers else { return }
    let touchLocaltion = touch.location(in: mapCanvas)
    for sublayer in sublayers {
      guard let shape = sublayer as? CAShapeLayer,
        let path = shape.path,
        shape.hitTest(touchLocaltion) != nil else { continue }
      let locationInsideRect = mapCanvas.layer.convert(touchLocaltion, to: shape)
      if path.contains(locationInsideRect) {
        if shape.fillColor == UIColor.red.cgColor {
          shape.fillColor = UIColor.cyan.cgColor
        } else {
          shape.fillColor = UIColor.red.cgColor
        }

      }
    }
  }
}

UPD:用于检查触摸是否在特定形状上的逻辑位于touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?)方法

Demo