【问题标题】:Reposition CGPath/UIBezierPath in View在视图中重新定位 CGPath/UIBezierPath
【发布时间】:2013-06-18 12:31:23
【问题描述】:

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

【问题讨论】:

  • 它们是根据什么绘制的?视图层?子层?形状层?
  • 它们被绘制在视图层上。

标签: ios uibezierpath cgpath


【解决方案1】:

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

移动 CGPath

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

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

然后您可以使用movedPath 以您已经在做的相同方式绘制。

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

yourPath = CGPathCreateCopyByTransformingPath(yourPath,
                                              &translation);

然后简单地重绘它。

移动形状层

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

更新:

如果您想使用形状图层,您只需创建一个新的 CAShapeLayer 并将其路径设置为您的 CGPath。由于 CAShapeLayer 是 Core Animation 的一部分,因此您需要 QuartzCore.framework。

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

[someView.layer addSublayer:shape];

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

shape.position = thePointYouWantToMoveTheShapeTo;

【讨论】:

  • 我尝试了您建议的第一个代码 CGAffineTransformMakeTranslation,但以我触摸的当前 x 和 y 作为参数。它似乎没有跟随触摸位置,并且有点增加路径的位置。
  • @jeraldov 您应该传入 x 和 y 的差异。例如,translationInView: 用于平移手势识别器。也就是说,如果你要移动形状很多,你应该考虑一个形状层。
  • 是的,因为我想在 TouchesMoved 事件上拖动/移动形状,所以我会移动很多形状。我将尝试使用形状层路线。你能给我一个关于如何做形状图层的示例或教程吗?谢谢。
  • @jeraldov 我已经更新了我的问题。它对形状层的解释是否足够?
  • 是的。我现在可以重新定位我的绘图了。
【解决方案2】:

/// 将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
}

【讨论】:

  • 翻译路径的边界不正确,假设我将图层从点 (0.0) 移动到点 (100, 100),但是当我打印 cgpath 的边界框时,它在点 (150, 200)。知道是什么问题。
【解决方案3】:

/// 为其提供 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
}

【讨论】:

    【解决方案4】:

    我做的和上面的其他答案有点不同。

    假设你要移动一个圆,首先我在全局变量中定义它的中心坐标和半径,像这样:

    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()重绘,所以圆会移动。

    希望它对某人有所帮助!

    【讨论】:

      猜你喜欢
      • 2013-05-20
      • 1970-01-01
      • 1970-01-01
      • 2023-03-28
      • 1970-01-01
      • 2013-12-22
      • 1970-01-01
      • 2018-10-28
      • 2023-03-13
      相关资源
      最近更新 更多