12

是否可以在视图上重新定位已绘制的 CGPath/UIBezierPath?我想移动或更改路径的位置,然后可能调用 drawinRect 方法以再次显示绘图。

4

4 回答 4

24

从您的问题看来,您正在使用内部的 Core Graphics 绘制路径drawRect:(与使用 a 相比CAShapeLayer),所以我将首先解释该版本。

移动 CGPath

您可以通过转换另一条路径来创建新路径。平移变换将变换后的对象在 x 和 y 上移动一定距离。因此,使用平移变换,您可以将现有路径在 x 和 y 中移动一定数量的点。

CGAffineTransform translation = CGAffineTransformMakeTranslation(xPixelsToMove,
                                                                 yPixelsToMove);
CGPathRef movedPath = CGPathCreateCopyByTransformingPath(originalCGPath,
                                                         &translation);

然后你可以使用movedPath你已经在做的同样的方式来绘制。

您也可以更改修改相同的路径

yourPath = CGPathCreateCopyByTransformingPath(yourPath,
                                              &translation);

并简单地重绘它。

移动形状图层

如果您使用的是形状图层,则移动它会更容易。然后您只需要使用该position属性更改图层的位置。

更新:

如果您想使用形状图层,您可以简单地创建一个新的 CAShapeLayer 并将其路径设置为您的 CGPath。你需要 QuartzCore.framework 因为 CAShapeLayer 是核心动画的一部分。

CAShapeLayer *shape = [CAShapeLayer layer];
shape.path = yourCGParth;
shape.fillColor = [UIColor redColor].CGColor;

[someView.layer addSublayer:shape];

然后要移动形状,您只需更改其位置。

shape.position = thePointYouWantToMoveTheShapeTo;
于 2013-06-18T13:41:46.673 回答
6

/// 将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
}
于 2018-05-13T07:38:57.107 回答
1

/// 为其提供 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
}
于 2018-05-13T07:37:02.753 回答
0

我这样做与上面的其他答案有点不同。

假设您要移动一个圆,首先我在全局变量中定义它的中心坐标和半径,如下所示:

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()
    }
}

每次触摸在圆内时,它的中心坐标都会更新,并且 UIView 会用 重绘setNeedDisplay(),因此圆会移动。

希望它可以帮助某人!

于 2020-06-04T17:35:42.757 回答