iosobjective-cuibezierpathquartz-core

How to append arrow head to UIBezierPath


I need help in adding arrow head to UIBezierPath. I have created multiple lines by using UIBezierPath, which are in different directions. Now, I want to create arrow head at the end point of the line.

I tried to add UIImage to UILable using NSAttributedString to UILable with NSTextAttachment.

But, here problem is arrow head is always down. And I want to align arrow along the line.

Here is my code:

    UIBezierPath *ShotPath = [UIBezierPath bezierPath];
    NSValue *PointValue = [[[PathArray objectAtIndex:i] valueForKey:@"ShotPath"] objectAtIndex:k];
    CGPoint FirstPoint; = [PointValue CGPointValue];
    [ShotPath moveToPoint:FirstPoint];

    CAShapeLayer *line = [CAShapeLayer layer];
    line.lineWidth = 4.0;
    line.path=ShotPath.CGPath;
    line.fillColor = [UIColor clearColor].CGColor;
    line.strokeColor = [UIColor colorWithRed:231/255.0 green:83/255.0 blue:73/255.0 alpha:1].CGColor;
    [[BaseView layer] addSublayer:line];
    NSValue *PointValue = [[[PathArray objectAtIndex:i] valueForKey:@"ShotPath"] objectAtIndex:[[[PathArray objectAtIndex:i] valueForKey:@"ShotPath"] count]-1];
    CGPoint OtherPoint = [PointValue CGPointValue];
    UILabel *lbl = [[UILabel alloc]initWithFrame:CGRectMake(OtherPoint.x-6, OtherPoint.y-8, 12, 12)];
    lbl.backgroundColor =[UIColor clearColor];
    NSTextAttachment *attachment = [[NSTextAttachment alloc] init];
    attachment.image = [UIImage imageNamed:@"DropDown_Icon"];
    NSAttributedString *attachmentString = [NSAttributedString attributedStringWithAttachment:attachment];
    lbl.attributedText = attachmentString;
    [lbl setTextColor:[UIColor blackColor]];
    lbl.font =[UIFont boldSystemFontOfSize:22.0];
    [BaseView addSubview:lbl];

Here is my current output :

enter image description here


Solution

  • By the reference of this answer:

    append arrowhead to UIBezierPath

    Solved my query: Answer:

    enter image description here

    - (void)viewDidLoad {
        [super viewDidLoad];
    
        UIBezierPath *path = [UIBezierPath bezierPath];
        CGPoint point1 = CGPointMake(100, 100);
        CGPoint point2 = CGPointMake(300, 300);
    
        [path moveToPoint:point1];
        [path addQuadCurveToPoint:point2 controlPoint:point1];
    
        CAShapeLayer *shape = [CAShapeLayer layer];
        shape.path = path.CGPath;
        shape.lineWidth = 10;
        shape.strokeColor = [UIColor blueColor].CGColor;
        shape.fillColor = [UIColor clearColor].CGColor;
        shape.frame = self.view.bounds;
        [self.view.layer addSublayer:shape];
    
        CGFloat angle = atan2f(point2.y - point1.y, point2.x - point1.x);
    
        CGFloat distance = 15.0;
        path = [UIBezierPath bezierPath];
        [path moveToPoint:point2];
        [path addLineToPoint:[self calculatePointFromPoint:point2 angle:angle + M_PI_2 distance:distance]]; // to the right
        [path addLineToPoint:[self calculatePointFromPoint:point2 angle:angle          distance:distance]]; // straight ahead
        [path addLineToPoint:[self calculatePointFromPoint:point2 angle:angle - M_PI_2 distance:distance]]; // to the left
        [path closePath];
    
        shape = [CAShapeLayer layer];
        shape.path = path.CGPath;
        shape.lineWidth = 2;
        shape.strokeColor = [UIColor redColor].CGColor;
        shape.fillColor = [UIColor redColor].CGColor;
        shape.frame = self.view.bounds;
        [self.view.layer addSublayer:shape];
    }
    - (CGPoint)calculatePointFromPoint:(CGPoint)point angle:(CGFloat)angle distance:(CGFloat)distance {
        return CGPointMake(point.x + cosf(angle) * distance, point.y + sinf(angle) * distance);
    }