We will use Occasion Strategies on CGPath
— both retrieved from UIBezierPath
or, a bit simpler, working straight with CGMutablePath
.
See the Apple docs below Occasion Strategies right here.
Relying on what you actually need to do, although, you won’t want to govern your path in any respect. You should utilize it as a masks … you need to use path incorporates(_ level: CGPoint)
… and so forth.
However — here’s a actually fast instance of utilizing CGPath
intersection(_:utilizing:)
I am going to make a couple of assumptions, comparable to you’re including a picture view to a view subclass; monitoring the contact started, moved, ended; utilizing a CAShapeLayer
to “draw” the trail define; and so forth.
Seems to be kinda like this (tapping wherever outdoors the grey body will “clip” the trail and fill it with inexperienced):
Easy UIView
subclass
- has a centered picture view, with some padding on the edges (so we will “draw” outdoors the picture)
- attracts a 2-point width path define
- closes the trail on touches ended
- has a public func to “clip” the drawn path with the picture view’s body
class MyCanvasView: UIView {
let imgView = UIImageView()
personal var myPath: CGMutablePath!
personal var shapeLayer: CAShapeLayer = CAShapeLayer()
override init(body: CGRect) {
tremendous.init(body: body)
commonInit()
}
required init?(coder: NSCoder) {
tremendous.init(coder: coder)
commonInit()
}
personal 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 isn't a picture set
imgView.backgroundColor = .systemYellow
self.backgroundColor = UIColor(white: 0.95, alpha: 1.0)
}
override func touchesBegan(_ touches: Set<UITouch>, with occasion: UIEvent?) {
guard let t = touches.first else { return }
let pt = t.location(in: self)
myPath = CGMutablePath()
myPath.transfer(to: pt)
shapeLayer.fillColor = UIColor.clear.cgColor
shapeLayer.path = myPath
}
override func touchesMoved(_ touches: Set<UITouch>, with occasion: 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 occasion: 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.body, rework: nil)
let clippedPath = imgPath.intersection(myPath)
shapeLayer.path = clippedPath
shapeLayer.fillColor = UIColor.inexperienced.cgColor
}
}
Take a look at View Controller class
class TestPathsVC: UIViewController {
let canvasView = MyCanvasView()
override func viewDidLoad() {
tremendous.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.picture = img
}
}
override func touchesBegan(_ touches: Set<UITouch>, with occasion: UIEvent?) {
canvasView.clipPath()
}
}