web-dev-qa-db-fra.com

Tracez une ligne avec un CALayer

J'essaie de tracer une ligne entre deux points à l'aide d'un CALayer. Voici mon code:

//positions a CALayer to be a line between a parent node and its subnodes.

-(void)makeLineLayer:(CALayer *)layer lineFromPointA:(CGPoint)pointA toPointB:(CGPoint)pointB{
    NSLog([NSString stringWithFormat:@"Coordinates: \n Ax: %f Ay: %f Bx: %f By: %f", pointA.x,pointA.y,pointB.x,pointB.y]);

    //find the length of the line:
    CGFloat length = sqrt((pointA.x - pointB.x) * (pointA.x - pointB.x) + (pointA.y -     pointB.y) * (pointA.y - pointB.y));
    layer.frame = CGRectMake(0, 0, 1, length);

    //calculate and set the layer's center:
    CGPoint center = CGPointMake((pointA.x+pointB.x)/2, (pointA.y+pointB.y)/2);
    layer.position = center;

    //calculate the angle of the line and set the layer's transform to match it.
    CGFloat angle = atan2f(pointB.y - pointA.y, pointB.x - pointA.x);
    layer.transform = CATransform3DMakeRotation(angle, 0, 0, 1);
}

Je sais que la longueur est calculée correctement et je suis à peu près sûr que le centre l'est également. Lorsque je l'exécute, les lignes affichées sont de la bonne longueur et passent par le point central entre les deux points, mais ne sont pas pivotées correctement. Au début, je pensais que la ligne pivotait autour du mauvais point d'ancrage. Je l'ai donc fait: layer.anchorPoint = center;, mais ce code ne montre aucune ligne à l'écran. Qu'est-ce que je fais mal

14
67cherries

Essaye ça...

-(void)makeLineLayer:(CALayer *)layer lineFromPointA:(CGPoint)pointA toPointB:(CGPoint)pointB
{
    CAShapeLayer *line = [CAShapeLayer layer];
    UIBezierPath *linePath=[UIBezierPath bezierPath];
    [linePath moveToPoint: pointA];
    [linePath addLineToPoint:pointB];
    line.path=linePath.CGPath;
    line.fillColor = nil;
    line.opacity = 1.0;
    line.strokeColor = [UIColor redColor].CGColor;
    [layer addSublayer:line];
}
32
Rajesh Choudhary

Voici une version Swift basée sur la réponse de Rajesh Choudhary :

Swift 2

func drawLine(onLayer layer: CALayer, fromPoint start: CGPoint, toPoint end: CGPoint) {
    let line = CAShapeLayer()
    let linePath = UIBezierPath()
    linePath.moveToPoint(start)
    linePath.addLineToPoint(end)
    line.path = linePath.CGPath
    line.fillColor = nil
    line.opacity = 1.0
    line.strokeColor = UIColor.redColor().CGColor
    layer.addSublayer(line)
}

Swift 3

func drawLine(onLayer layer: CALayer, fromPoint start: CGPoint, toPoint end: CGPoint) {
    let line = CAShapeLayer()
    let linePath = UIBezierPath()
    linePath.move(to: start)
    linePath.addLine(to: end)
    line.path = linePath.cgPath
    line.fillColor = nil
    line.opacity = 1.0
    line.strokeColor = UIColor.red.cgColor
    layer.addSublayer(line)
}
17
yuji

Voici une version de Swift 3 basée sur la réponse de Rajesh Choudhary :

func drawLine(onLayer layer: CALayer, fromPoint start: CGPoint, toPoint end:CGPoint) {
        let line = CAShapeLayer()
        let linePath = UIBezierPath()
        linePath.move(to: start)
        linePath.addLine(to: end)
        line.path = linePath.cgPath
        line.fillColor = nil
        line.opacity = 1.0
        line.strokeColor = UIColor.green.cgColor
        layer.addSublayer(line)
    }
0
Yi Jiang