如何在视图上更新已绘制的CGPath
/UIBezierPath
的位置?我想移动或更改路径的位置,然后可能调用drawInRect
方法来重新渲染路径。
如何在视图上更新已绘制的CGPath
/UIBezierPath
的位置?我想移动或更改路径的位置,然后可能调用drawInRect
方法来重新渲染路径。
根据您的问题,看起来您正在使用Core Graphics在drawRect:
内绘制路径(与使用CAShapeLayer
相比),因此我将首先解释这个版本。
您可以通过转换另一个路径来创建新路径。 平移变换将变换对象沿x和y移动一定距离。 因此,使用平移变换,您可以将现有路径在x和y方向上移动一定数量的点。
CGAffineTransform translation = CGAffineTransformMakeTranslation(xPixelsToMove,
yPixelsToMove);
CGPathRef movedPath = CGPathCreateCopyByTransformingPath(originalCGPath,
&translation);
然后,您可以使用movedPath
以与您已经执行的方式相同的方式进行绘制。
您还可以更改修改相同的路径。
yourPath = CGPathCreateCopyByTransformingPath(yourPath,
&translation);
然后简单地重新绘制它。
如果您正在使用形状图层,则移动它会更容易。然后,您只需要使用position
属性更改图层的位置即可。
如果您想要使用形状图层,您可以简单地创建一个新的CAShapeLayer,并将其路径设置为您的CGPath。由于CAShapeLayer是核心动画的一部分,因此您需要QuartzCore.framework。
CAShapeLayer *shape = [CAShapeLayer layer];
shape.path = yourCGParth;
shape.fillColor = [UIColor redColor].CGColor;
[someView.layer addSublayer:shape];
然后,要移动形状,只需更改其位置即可。
shape.position = thePointYouWantToMoveTheShapeTo;
将cgPath从中心点移动到指定点,无需移动形状层。移动路径会使应用程序更加流畅。
func translate(path : CGPath?, by point: CGPoint) -> CGPath? {
let bezeirPath = UIBezierPath()
guard let prevPath = path else {
return nil
}
bezeirPath.cgPath = prevPath
bezeirPath.apply(CGAffineTransform(translationX: point.x, y: point.y))
return bezeirPath.cgPath
}
/// 提供cgpath并通过给定的点进行平移。
func translate(path : CGPath?, by point: CGPoint) -> CGPath? {
let bezeirPath = UIBezierPath()
guard let prevPath = path else {
return nil
}
bezeirPath.cgPath = prevPath
bezeirPath.apply(CGAffineTransform(translationX: point.x, y: point.y))
return bezeirPath.cgPath
}
我与其他上面的答案有所不同。
假设您要移动一个圆,首先我将其中心坐标和半径定义为全局变量,像这样:
var center: CGPoint = CGPoint(x: UIScreen.main.bounds.width/2, y: UIScreen.main.bounds.height/2)
var radius: CGFloat = 10
override func draw(_ rect: CGRect) {
super.draw(rect)
drawCircle()
}
func drawCircle() {
let circle = UIBezierPath(
arcCenter: self.center,
radius: CGFloat(self.radius),
startAngle: CGFloat(0),
endAngle: CGFloat(2*Double.pi),
clockwise: true)
let circleLayer = CAShapeLayer()
circleLayer.path = circle.cgPath
circleLayer.fillColor = UIColor.clear.cgColor
circleLayer.strokeColor = UIColor.black.cgColor
circleLayer.lineWidth = 10.0
layer.addSublayer(circleLayer)
}
在UIView内部,我有一个touchesMoved()方法,就像这样:
override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?){
if let touch = touches.first {
let pos = touch.location(in: self)
if (pow(pos.x-self.center.x,2) + pow(pos.y-self.center.y,2) <= pow(self.radius,2)){
self.center = CGPoint(x: pos.x, y: pos.y)
}
setNeedsDisplay()
}
}
setNeedDisplay()
重新绘制UIView,因此圆形会移动。