我需要计算两个不规则 UIBezierpath 的交集,例如表示不规则形状的闭合路径。问题是我什至不知道如何开始。我已经搜索了可以提供帮助的库,但我发现的唯一的东西是 git 存储库缺少文件,因此它无法编译。
我们可以在
CGPath
上使用实例方法——可以从 UIBezierPath
检索,或者更简单一点,直接使用 CGMutablePath
。
请参阅实例方法此处下的 Apple 文档。
但是,根据您真正想要做什么,您可能根本不需要操纵您的路径。您可以将其用作遮罩...您可以使用路径
contains(_ point: CGPoint)
...等等。
但是 - 这是一个使用
CGPath
intersection(_:using:)
的快速示例
我将做出一些假设,例如您将图像视图添加到视图子类中;跟踪触摸的开始、移动、结束;使用
CAShapeLayer
“绘制”路径轮廓;等等
看起来有点像这样(点击灰色框外的任何地方都会“剪切”路径并用绿色填充):
简单
UIView
子类
class MyCanvasView: UIView {
let imgView = UIImageView()
private var myPath: CGMutablePath!
private var shapeLayer: CAShapeLayer = CAShapeLayer()
override init(frame: CGRect) {
super.init(frame: frame)
commonInit()
}
required init?(coder: NSCoder) {
super.init(coder: coder)
commonInit()
}
private func commonInit() {
imgView.translatesAutoresizingMaskIntoConstraints = false
addSubview(imgView)
NSLayoutConstraint.activate([
imgView.topAnchor.constraint(equalTo: topAnchor, constant: 60.0),
imgView.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 60.0),
imgView.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -60.0),
imgView.bottomAnchor.constraint(equalTo: bottomAnchor, constant: -60.0),
])
shapeLayer.fillColor = UIColor.clear.cgColor
shapeLayer.strokeColor = UIColor.systemRed.cgColor
shapeLayer.lineWidth = 2
self.layer.addSublayer(shapeLayer)
// in case there is no image set
imgView.backgroundColor = .systemYellow
self.backgroundColor = UIColor(white: 0.95, alpha: 1.0)
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
guard let t = touches.first else { return }
let pt = t.location(in: self)
myPath = CGMutablePath()
myPath.move(to: pt)
shapeLayer.fillColor = UIColor.clear.cgColor
shapeLayer.path = myPath
}
override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
guard let t = touches.first else { return }
let pt = t.location(in: self)
myPath.addLine(to: pt)
shapeLayer.path = myPath
}
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
guard let t = touches.first else { return }
let pt = t.location(in: self)
myPath.closeSubpath()
shapeLayer.path = myPath
}
public func clipPath() {
let imgPath = CGMutablePath(rect: imgView.frame, transform: nil)
let clippedPath = imgPath.intersection(myPath)
shapeLayer.path = clippedPath
shapeLayer.fillColor = UIColor.green.cgColor
}
}
测试视图控制器类
class TestPathsVC: UIViewController {
let canvasView = MyCanvasView()
override func viewDidLoad() {
super.viewDidLoad()
canvasView.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(canvasView)
let g = view.safeAreaLayoutGuide
NSLayoutConstraint.activate([
canvasView.topAnchor.constraint(equalTo: g.topAnchor, constant: 40.0),
canvasView.leadingAnchor.constraint(equalTo: g.leadingAnchor, constant: 20.0),
canvasView.trailingAnchor.constraint(equalTo: g.trailingAnchor, constant: -20.0),
canvasView.heightAnchor.constraint(equalTo: canvasView.widthAnchor),
])
if let img = UIImage(named: "testPic") {
canvasView.imgView.image = img
}
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
canvasView.clipPath()
}
}