That greycolour is UIImageView and the White colour font is Image.
That image Placed inside UIImageView.
I like to colour only inside the font ,not an whole UIImageview for that i am going to find out the coordinates of the image .
i am new to this kind of concept so kindly some one guide me how to colour only inside the image ,there are 50+ images is there ,it is not static so give some good idea .
This is the code i am using to draw inside the UIImageView:
-(void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [[event allTouches] anyObject];
touchPoint = [touch locationInView:self.imgColor];
UIBezierPath *path = [UIBezierPath bezierPath];
[path moveToPoint:CGPointMake(touchPoint.x,touchPoint.y)];
[path addLineToPoint:CGPointMake(startingPoint.x,startingPoint.y)];
startingPoint=touchPoint;
CAShapeLayer *shapeLayer = [CAShapeLayer layer];
shapeLayer.path = [path CGPath];
shapeLayer.strokeColor = [[UIColor blueColor] CGColor];
shapeLayer.lineWidth = 3.0;
shapeLayer.fillColor = [[UIColor redColor] CGColor];
[self.imgColor.layer addSublayer:shapeLayer];
[arrLayer addObject:shapeLayer];
NSLog(#"Touch moving point =x : %f Touch moving point =y : %f", touchPoint.x, touchPoint.y);
}
Use this custom UIImage view:
CustomView.h
#interface CustomView : UIImageView
#end
CustomView.m
#interface CustomView ()
{
CGPoint touchPoint,startingPoint;
UIView *drawingView;
}
#end
#implementation CustomView
-(void)awakeFromNib
{
drawingView = [[UIView alloc] initWithFrame:self.bounds];
drawingView.backgroundColor = [UIColor clearColor];
[self addSubview:drawingView];
[self updateMask];
}
- (void)updateMask
{
CALayer *maskLayer = [CALayer layer];
maskLayer.geometryFlipped = YES;
maskLayer.contents = (id)self.image.CGImage;
switch (self.contentMode)
{
case UIViewContentModeScaleToFill:
maskLayer.contentsGravity = kCAGravityResize;
break;
case UIViewContentModeScaleAspectFit:
maskLayer.contentsGravity = kCAGravityResizeAspect;
break;
case UIViewContentModeScaleAspectFill:
maskLayer.contentsGravity = kCAGravityResizeAspectFill;
break;
case UIViewContentModeCenter:
maskLayer.contentsGravity = kCAGravityCenter;
break;
case UIViewContentModeTop:
maskLayer.contentsGravity = kCAGravityTop;
break;
case UIViewContentModeBottom:
maskLayer.contentsGravity = kCAGravityBottom;
break;
case UIViewContentModeLeft:
maskLayer.contentsGravity = kCAGravityLeft;
break;
case UIViewContentModeRight:
maskLayer.contentsGravity = kCAGravityRight;
break;
case UIViewContentModeTopLeft:
maskLayer.contentsGravity = kCAGravityTopLeft;
break;
case UIViewContentModeTopRight:
maskLayer.contentsGravity = kCAGravityTopRight;
break;
case UIViewContentModeBottomLeft:
maskLayer.contentsGravity = kCAGravityBottomLeft;
break;
case UIViewContentModeBottomRight:
maskLayer.contentsGravity = kCAGravityBottomRight;
break;
default:
break;
}
maskLayer.frame = drawingView.bounds;
drawingView.layer.mask = maskLayer;
}
- (void)setImage:(UIImage *)image
{
[super setImage:image];
[self updateMask];
}
- (void)layoutSubviews
{
[super layoutSubviews];
drawingView.frame = self.bounds;
drawingView.layer.mask.frame = drawingView.bounds;
}
-(void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [[event allTouches] anyObject];
touchPoint = [touch locationInView:self];
if (!CGPointEqualToPoint(startingPoint, CGPointZero))
{
UIBezierPath *path = [UIBezierPath bezierPath];
[path moveToPoint:CGPointMake(touchPoint.x,touchPoint.y)];
[path addLineToPoint:CGPointMake(startingPoint.x,startingPoint.y)];
CAShapeLayer *shapeLayer = [CAShapeLayer layer];
shapeLayer.path = [path CGPath];
shapeLayer.strokeColor = [[UIColor blueColor] CGColor];
shapeLayer.lineWidth = 3.0;
shapeLayer.fillColor = [[UIColor redColor] CGColor];
[drawingView.layer addSublayer:shapeLayer];
}
startingPoint=touchPoint;
// [arrLayer addObject:shapeLayer];
NSLog(#"Touch moving point =x : %f Touch moving point =y : %f", touchPoint.x, touchPoint.y);
}
- (void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(nullable UIEvent *)event;
{
startingPoint = CGPointZero;
}
#end
Related
I am working on an iPhone application using Objective C, where I need to make a border animation to UILabel.
I tried below code using CABasicAnimation :
CABasicAnimation* borderAnimation = [CABasicAnimation animationWithKeyPath:#"borderWidth"];
[borderAnimation setFromValue:[NSNumber numberWithFloat:4.0f]];
[borderAnimation setToValue:[NSNumber numberWithFloat:0.0f]];
[borderAnimation setRepeatCount:1.0];
[borderAnimation setAutoreverses:NO];
[borderAnimation setDuration:0.7f];
[focusScannerView.layer addAnimation:borderAnimation forKey:#"animateBorder"];
But border animation is not working perfectly. Anybody have an idea of how would I do this? Thank you in Advance.
#import "ViewController.h"
#interface ViewController ()
{
UIBezierPath *path;
CAShapeLayer *shapeLayer;
int lineNo;
}
#property (nonatomic, weak) IBOutlet UILabel *textLabel;
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
path = [UIBezierPath bezierPath];
shapeLayer = [CAShapeLayer layer];
shapeLayer.strokeColor = [[UIColor blueColor] CGColor];
shapeLayer.lineWidth = 3.0;
shapeLayer.fillColor = [[UIColor clearColor] CGColor];
[_textLabel addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(startAnimation)]];
// Do any additional setup after loading the view, typically from a nib.
}
-(void)startAnimation{
lineNo = 0;
[self drawLine:lineNo];
}
-(void)drawLine:(int)line{
CGPoint startPoint;
CGPoint endPoint;
switch (line) {
case 0:
startPoint = CGPointMake(self.textLabel.frame.origin.x, self.textLabel.frame.origin.y);
endPoint = CGPointMake(CGRectGetMaxX(self.textLabel.frame), self.textLabel.frame.origin.y);
break;
case 1:
startPoint = CGPointMake(CGRectGetMaxX(self.textLabel.frame), self.textLabel.frame.origin.y);
endPoint = CGPointMake(CGRectGetMaxX(self.textLabel.frame), CGRectGetMaxY(self.textLabel.frame));
break;
case 2:
startPoint = CGPointMake(CGRectGetMaxX(self.textLabel.frame), CGRectGetMaxY(self.textLabel.frame));
endPoint = CGPointMake(self.textLabel.frame.origin.x, CGRectGetMaxY(self.textLabel.frame));
break;
case 3:
startPoint = CGPointMake(self.textLabel.frame.origin.x, CGRectGetMaxY(self.textLabel.frame));
endPoint = CGPointMake(self.textLabel.frame.origin.x, self.textLabel.frame.origin.y);
break;
default:
return;
}
[self animateStartPoint:startPoint andEndPoint:endPoint];
}
-(void)animateStartPoint:(CGPoint) startPoint andEndPoint:(CGPoint)endPoint{
[path moveToPoint:startPoint];
[path addLineToPoint:endPoint];
shapeLayer.path = [path CGPath];
CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:#"strokeEnd"];
animation.duration = 5;
animation.removedOnCompletion = NO;
animation.fromValue = #(0);
animation.toValue = #(1);
animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear];
[shapeLayer addAnimation:animation forKey:#"drawLineAnimation"];
[self.view.layer addSublayer:shapeLayer];
lineNo++;
[self drawLine:lineNo];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
I have made sample demo for creating random path using UIBezier object.
I know I asked same type of question which was already asked, But I was not able to solve so.
Code
#implementation RandomShape
#synthesize randomPath,size,color;
- (void)drawRect:(CGRect)rect {
self.size = 1.0;
[self.color setStroke];
[self.randomPath stroke];
}
-(id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if(self)
{
self.randomPath = [UIBezierPath bezierPath];
[self.randomPath stroke];
}
return self;
}
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [touches anyObject];
[self.randomPath moveToPoint:[touch locationInView:self]];
[self.randomPath setLineWidth:size];
[self setNeedsDisplay];
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *mytouch=[touches anyObject];
[self.randomPath addLineToPoint:[mytouch locationInView:self]];
[self setNeedsDisplay];
}
-(void)clearRandomShape
{
self.randomPath = nil; //Set current path nil
self.randomPath = [UIBezierPath bezierPath]; //Create new path
[self.randomPath setLineWidth:2.0];
[self setNeedsDisplay];
}
1) I have select the colour from the picker view.
Now My problem is,
-->When I select colour from the picker it change all previous line colour as it is.
(It displays last colour which I choose in all random path.)
--->My requirement is I wand different different colour's random Path.
Please help Me I am confuse.
Thank you.
Write this code wherever you want to create path..
//path 1
UIBezierPath *linePath = [[UIBezierPath alloc] init];
[linePath moveToPoint:CGPointMake(100, 100)];
[linePath addLineToPoint:CGPointMake(275, 100)];
CAShapeLayer *shapeLayer = [CAShapeLayer layer];
shapeLayer.strokeColor = [UIColor redColor].CGColor;
shapeLayer.fillColor = [UIColor clearColor].CGColor;
shapeLayer.lineWidth = 2;
shapeLayer.lineJoin = kCALineJoinRound;
shapeLayer.lineCap = kCALineCapRound;
shapeLayer.path = linePath.CGPath;
[self.view.layer addSublayer:shapeLayer];
//Path 2
UIBezierPath *verticalLinePath = [[UIBezierPath alloc] init];
[verticalLinePath moveToPoint:CGPointMake(100, 200)];
[verticalLinePath addLineToPoint:CGPointMake(275, 200)];
CAShapeLayer *horizontalLayer = [CAShapeLayer layer];
horizontalLayer.strokeColor = [UIColor greenColor].CGColor;
horizontalLayer.fillColor = [UIColor clearColor].CGColor;
horizontalLayer.lineWidth = 2;
horizontalLayer.lineJoin = kCALineJoinRound;
horizontalLayer.lineCap = kCALineCapRound;
horizontalLayer.path = verticalLinePath.CGPath;
[self.view.layer addSublayer:horizontalLayer];
//Path
UIBezierPath *path3 = [[UIBezierPath alloc] init];
[path3 moveToPoint:CGPointMake(100, 300)];
[path3 addLineToPoint:CGPointMake(275, 300)];
CAShapeLayer *horizontalLayer3 = [CAShapeLayer layer];
horizontalLayer3.strokeColor = [UIColor blueColor].CGColor;
horizontalLayer3.fillColor = [UIColor cyanColor].CGColor;
horizontalLayer3.lineWidth = 2;
horizontalLayer3.lineJoin = kCALineJoinRound;
horizontalLayer3.lineCap = kCALineCapRound;
horizontalLayer3.path = path3.CGPath;
[self.view.layer addSublayer:horizontalLayer3];
Output of this code is ->
Before Colouring the image:
After Colouring the Image:
This is my code :
-(void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [[event allTouches] anyObject];
touchPoint = [touch locationInView:self.imgColor];
UIBezierPath *path = [UIBezierPath bezierPath];
[path moveToPoint:CGPointMake(touchPoint.x,touchPoint.y)];
[path addLineToPoint:CGPointMake(startingPoint.x,startingPoint.y)];
startingPoint=touchPoint;
CAShapeLayer *shapeLayer = [CAShapeLayer layer];
shapeLayer.path = [path CGPath];
shapeLayer.strokeColor = [[UIColor blueColor] CGColor];
shapeLayer.lineWidth = 3.0;
shapeLayer.fillColor = [[UIColor redColor] CGColor];
[self.imgColor.layer addSublayer:shapeLayer];
[arrLayer addObject:shapeLayer];
NSLog(#"Touch moving point =x : %f Touch moving point =y : %f", touchPoint.x, touchPoint.y);
}
Depend upon the user touch, it's drawing a line inside UIImageView.
What i need is :
If image size is to small, then I don't like to allow draw outside the image.
Within the image user have to draw ,is there any way? Please suggest me.
Add this code to your touch handing view.
override func pointInside(point: CGPoint, withEvent event: UIEvent?) -> Bool {
return CGRectContainsPoint(doggyImage.frame, point)
}
Code provided in the first comment if (!CGRectContainsPoint(doggyImage.frame, touchPoint)) is some condition that you can use to check whether the touch point is in one specific view, where I think you should use to compare with your dog image (I don't know which variable it is, so I used doggyImage. Maybe self.imgColor is the correct one or not).
And for simplest solution, you need to do at least two things
If touchesBegan outside the doggyImage, don't do anything, just return.
Prevent lines been draw from inside to outside, so use the same condition, and apply the same code you used in touchesEnd to handle something like stopDrawLine.
More advanced method would include computing the nearest point from the touch to the image if it's outside, and draw it on the edge.
BTW, currently in your touchesMoved, you created one new UIBezierPath every single touch point, resulting in hundreds of discrete small pieces of line. You may want to try to new a path when touchesBegan and addLineToPoint in touchesMoved. So that the whole line is in one path, and you can therefore offer freatures like "undo".
take one CGRect object Globally assign its value as follow
CGRect imagerect = CGRectMake(imgColor.center.x - (imgColor.image.size.width/2 + imgColor.frame.origin.x), imgColor.center.y - (imgColor.image.size.height/2+ imgColor.frame.origin.y), imgColor.image.size.width, imgColor.image.size.height);
now in touchesMoved method put one condition before drawing if( CGRectContainsPoint(imagerect, touchPoint))
so the method will be like
-(void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [[event allTouches] anyObject];
touchPoint = [touch locationInView:self.imgColor];
if( CGRectContainsPoint(imagerect, touchPoint))
{
UIBezierPath *path = [UIBezierPath bezierPath];
[path moveToPoint:CGPointMake(touchPoint.x,touchPoint.y)];
[path addLineToPoint:CGPointMake(startingPoint.x,startingPoint.y)];
startingPoint=touchPoint;
CAShapeLayer *shapeLayer = [CAShapeLayer layer];
shapeLayer.path = [path CGPath];
shapeLayer.strokeColor = [[UIColor blueColor] CGColor];
shapeLayer.lineWidth = 3.0;
shapeLayer.fillColor = [[UIColor redColor] CGColor];
[self.imgColor.layer addSublayer:shapeLayer];
[arrLayer addObject:shapeLayer];
NSLog(#"Touch moving point =x : %f Touch moving point =y : %f", touchPoint.x, touchPoint.y);
}
}
Might be this is not perfect solution but i try to make same as your requirements. please try with this
#import "ViewController.h"
#interface ViewController ()
{
CGPoint touchPoint,startingPoint;
CALayer *layer;
float x1;
float y1;
IBOutlet UIImageView *imgColor;
}
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
layer = [CALayer layer];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
}
-(void)viewDidAppear:(BOOL)animated
{
CGSize scaledImageSize = imgColor.image.size;
CGRect imageFrame = CGRectMake(roundf(0.5f*(CGRectGetWidth(imgColor.bounds)-scaledImageSize.width)), roundf(0.5f*(CGRectGetHeight(imgColor.bounds)-scaledImageSize.height)), roundf(scaledImageSize.width), roundf(scaledImageSize.height));
x1 = imageFrame.origin.x ;
y1 = imageFrame.origin.y ;
}
- (UIColor*)getRGBAsFromImage:(UIImage*)image atX:(int)x andY:(int)y
{
if (x < 0 || y<0 || x> image.size.width || y > image.size.height) {
return nil;
}
// First get the image into your data buffer
CGImageRef imageRef = [image CGImage];
NSUInteger width = CGImageGetWidth(imageRef);
NSUInteger height = CGImageGetHeight(imageRef);
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
unsigned char *rawData = (unsigned char*) calloc(height * width * 4, sizeof(unsigned char));
NSUInteger bytesPerPixel = 4;
NSUInteger bytesPerRow = bytesPerPixel * width;
NSUInteger bitsPerComponent = 8;
CGContextRef context = CGBitmapContextCreate(rawData, width, height,
bitsPerComponent, bytesPerRow, colorSpace,
kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big);
CGColorSpaceRelease(colorSpace);
CGContextDrawImage(context, CGRectMake(0, 0, width, height), imageRef);
CGContextRelease(context);
// Now your rawData contains the image data in the RGBA8888 pixel format.
NSUInteger byteIndex = (bytesPerRow * y) + x * bytesPerPixel;
CGFloat alpha = ((CGFloat) rawData[byteIndex + 3] ) / 255.0f;
CGFloat red = ((CGFloat) rawData[byteIndex] ) / alpha;
CGFloat green = ((CGFloat) rawData[byteIndex + 1] ) / alpha;
CGFloat blue = ((CGFloat) rawData[byteIndex + 2] ) / alpha;
byteIndex += bytesPerPixel;
if (red >= 0 || green >= 0 || blue >= 0) {
return [UIColor colorWithRed:red green:green blue:blue alpha:alpha];
}
return nil;
}
-(void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [[event allTouches] anyObject];
touchPoint = [touch locationInView:imgColor];
;
if ([self getRGBAsFromImage:imgColor.image atX:touchPoint.x - x1 andY:touchPoint.y - y1] && !(touchPoint.x == 0 && touchPoint.y == 0)) {
UIBezierPath *path = [UIBezierPath bezierPath];
[path moveToPoint:CGPointMake(touchPoint.x,touchPoint.y)];
[path addLineToPoint:CGPointMake(startingPoint.x,startingPoint.y)];
startingPoint=touchPoint;
CAShapeLayer *shapeLayer = [CAShapeLayer layer];
shapeLayer.path = [path CGPath];
shapeLayer.strokeColor = [[UIColor blueColor] CGColor];
shapeLayer.lineWidth = 1.0;
shapeLayer.fillColor = [[UIColor redColor] CGColor];
[imgColor.layer addSublayer:shapeLayer];
}
}
- (void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(nullable UIEvent *)event;
{
touchPoint = CGPointMake(0, 0);
}
#end
I have implemented a basic line drawing animation for a progress bar.The line has a round cap edge.When I moving the slider the line drawing the ending of line is having a rounded cap but in the starting its a square. below is the code I am using am i missing anything??
Image Attached: expected output
Below Code I tried
#interface ViewController ()
{
CGPoint center;
CGFloat radius;
}
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
center = CGPointMake(200.0, 200.0);
self.view.layer.backgroundColor = [[UIColor grayColor] CGColor];
}
- (IBAction)greenSlider:(UISlider *)sender {
[self.view.layer addSublayer:[self drawArcAtCenter:center startAngle:sender.minimumValue endAngle:sender.value radius:100.0 withColor:[UIColor greenColor]]];
}
- (IBAction)blueSlider:(UISlider *)sender {
int value = (int)sender.value;
if (value > 360) {
value = value % 90;
}
[self.view.layer addSublayer:[self drawArcAtCenter:center startAngle:sender.minimumValue endAngle:(float)value radius:100 withColor:[UIColor blueColor]]];
}
- (CAShapeLayer *) drawArcAtCenter:(CGPoint)newCenter startAngle:(CGFloat)sAngle endAngle:(CGFloat)bAngle radius:(CGFloat) radious withColor:(UIColor*) color
{
CGFloat begAngle = sAngle * 3.1459 / 180.0;
CGFloat endAngle = bAngle * 3.1459 / 180.0;
CAShapeLayer *layer = [CAShapeLayer layer];
UIBezierPath *path = [UIBezierPath bezierPath];
[path addArcWithCenter:newCenter radius:radious startAngle:begAngle endAngle:endAngle clockwise:YES];
layer.path = [path CGPath];
layer.strokeColor = [color CGColor];
layer.fillColor = [[UIColor clearColor] CGColor];;
layer.lineWidth = 50.0;
layer.strokeEnd = 50.0f;
layer.lineCap = kCALineCapRound;
layer.cornerRadius = 30.0f;
return layer;
}
I am creating a line in ipad as user touch the screen and and drag the finger. Problem is line is creating on every point in by (touchMoved:) we we drag it. But in last it should only one not many. How can I erase or remove last line after created new one? Here is my code:
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
if(ArrowDraw==YES){
NSLog(#"ArrowDrawing");
if ([[event allTouches]count]==1){
UITouch *touch = [touches anyObject];
CGPoint currentPoint = [touch locationInView:FullImageView];
UIGraphicsBeginImageContext(self.view.frame.size);
[self.tempDrawImage.image drawInRect:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height)];
CGContextMoveToPoint(UIGraphicsGetCurrentContext(), firstPoint.x, firstPoint.y);
CGContextAddLineToPoint(UIGraphicsGetCurrentContext(), currentPoint.x, currentPoint.y);
CGContextSetLineCap(UIGraphicsGetCurrentContext(), kCGLineCapRound);
CGContextSetLineWidth(UIGraphicsGetCurrentContext(), 1 );
CGContextSetRGBStrokeColor(UIGraphicsGetCurrentContext(), red, green, blue, 1.0);
CGContextSetBlendMode(UIGraphicsGetCurrentContext(),kCGBlendModeNormal);
CGContextStrokePath(UIGraphicsGetCurrentContext());
self.tempDrawImage.image = UIGraphicsGetImageFromCurrentImageContext();
[self.tempDrawImage setAlpha:opacity];
UIGraphicsEndImageContext();
//firstPoint = currentPoint;
NSLog(#"TouchMoving x=%f y=%f",firstPoint.x,firstPoint.y);
}
UIGraphicsBeginImageContext(self.FullImageView.frame.size);
[self.FullImageView.image drawInRect:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height) blendMode:kCGBlendModeNormal alpha:1.0];
[self.tempDrawImage.image drawInRect:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height) blendMode:kCGBlendModeNormal alpha:opacity];
self.FullImageView.image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
self.tempDrawImage.hidden=YES;
}
}
The key is to not update the image, but rather just draw the arrow on top of the image. Then replace the arrow with another as the touchesMoved come in.
For example, I might use the QuartzCore.framework by adding it to your target's "Link Binary With Libraries" and add the following line to the start of your .m:
#import <QuartzCore/QuartzCore.h>
Then you can define a new ivar for your CAShapeLayer:
CAShapeLayer *shapeLayer;
Finally, then update your touchesMoved to something like:
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
if (ArrowDraw==YES){
if ([[event allTouches]count]==1) {
UITouch *touch = [touches anyObject];
CGPoint currentPoint = [touch locationInView:FullImageView];
if (!shapeLayer)
{
shapeLayer = [CAShapeLayer layer];
shapeLayer.lineWidth = 1;
shapeLayer.strokeColor = [[UIColor blackColor] CGColor];
shapeLayer.fillColor = [[UIColor clearColor] CGColor];
[FullImageView.layer addSublayer:shapeLayer];
}
UIBezierPath *path = [UIBezierPath bezierPath];
[path moveToPoint:firstPoint];
[path addLineToPoint:currentPoint];
shapeLayer.path = [path CGPath];
}
}
}
You can modify that UIBezierPath to include the arrowhead if you need that, too, for example:
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
if (ArrowDraw==YES){
if ([[event allTouches]count]==1) {
UITouch *touch = [touches anyObject];
CGPoint currentPoint = [touch locationInView:FullImageView];
if (!shapeLayer) {
[self createShapeLayer];
}
shapeLayer.path = [[self arrowPathFrom:firstPoint to:currentPoint arrowheadSize:10.0] CGPath];
}
}
}
- (void)createShapeLayer
{
shapeLayer = [CAShapeLayer layer];
shapeLayer.lineWidth = 1;
shapeLayer.strokeColor = [[UIColor blackColor] CGColor];
shapeLayer.fillColor = [[UIColor clearColor] CGColor];
[FullImageView.layer addSublayer:shapeLayer];
}
- (UIBezierPath *)arrowPathFrom:(CGPoint)start to:(CGPoint)end arrowheadSize:(CGFloat)arrowheadSize
{
UIBezierPath *path = [UIBezierPath bezierPath];
[path moveToPoint:start];
[path addLineToPoint:end];
// add arrowhead
CGFloat angle = atan2(end.y - start.y, end.x - start.x) + M_PI * 3.0 / 4.0;
[path addLineToPoint:CGPointMake(cos(angle) * arrowheadSize + end.x, sin(angle) * arrowheadSize + end.y)];
[path addLineToPoint:end];
angle = atan2(end.y - start.y, end.x - start.x) - M_PI * 3.0 / 4.0;
[path addLineToPoint:CGPointMake(cos(angle) * arrowheadSize + end.x, sin(angle) * arrowheadSize + end.y)];
[path addLineToPoint:end];
return path;
}