答案 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?)
方法