I'm exploring making a doodle app where the user draws pictures with their finger and I've come across several different ways of drawing lines to the screen. I've seen code anywhere from:
- (void)drawRect:(CGRect)rect // (5)
{
[[UIColor blackColor] setStroke];
[path stroke];
}
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [touches anyObject];
CGPoint p = [touch locationInView:self];
[path moveToPoint:p];
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [touches anyObject];
CGPoint p = [touch locationInView:self];
[path addLineToPoint:p]; // (4)
[self setNeedsDisplay];
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
[self touchesMoved:touches withEvent:event];
}
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event
{
[self touchesEnded:touches withEvent:event];
}
to:
mouseSwiped = YES;
UITouch *touch = [touches anyObject];
CGPoint currentPoint = [touch locationInView:self.view];
UIGraphicsBeginImageContext(self.view.frame.size);
[self.tempDrawImage.image drawInRect:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height)];
CGContextMoveToPoint(UIGraphicsGetCurrentContext(), lastPoint.x, lastPoint.y);
CGContextAddLineToPoint(UIGraphicsGetCurrentContext(), currentPoint.x, currentPoint.y);
CGContextSetLineCap(UIGraphicsGetCurrentContext(), kCGLineCapRound);
CGContextSetLineWidth(UIGraphicsGetCurrentContext(), brush );
CGContextSetRGBStrokeColor(UIGraphicsGetCurrentContext(), red, green, blue, 1.0);
CGContextSetBlendMode(UIGraphicsGetCurrentContext(),kCGBlendModeNormal);
CGContextStrokePath(UIGraphicsGetCurrentContext());
self.tempDrawImage.image = UIGraphicsGetImageFromCurrentImageContext();
[self.tempDrawImage setAlpha:opacity];
UIGraphicsEndImageContext();
lastPoint = currentPoint;
and the last method (one I came up with that makes the most sense for me at least)
- (void) viewDidLoad{
UIPanGestureRecognizer* pan = [[UIPanGestureRecognizer alloc]initWithTarget:self action:#selector(drawImage:)];
[self.view addGestureRecognizer:pan];
pan.delegate = self;
paths = [[NSMutableArray alloc]init];
}
- (void) drawImage:(UIPanGestureRecognizer*)pan{
CGPoint point = [pan translationInView:self.view];
[paths addObject:[NSValue valueWithCGPoint:point]];
}
In the last implementation, I would store the points the user is dragging along and draw a line as they draw. I feel like that would be kind of intensive with a lot of overhead though since there's a lot of drawing going on while the user is interacting with the app.
So my question is, is there a best practice/best way to do drawing? Does Apple prefer a particular way over the other and what are the advantages/disadvantages of doing it each way?
A better way is to use the users touch points as points on a UIBezierPath. See session 233 WWDC 2012... http://developer.apple.com/itunes/?destination=adc.apple.com.16351493766
Related
Basically I just want to make an eraser just like in Paint. I want to erase parts of a UIImageView just with my finger. I use the following code, however, it erases only with small strokes, while I want it to erase until I pull my finger off:
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [touches anyObject];
lastTouch = [touch locationInView:bg];
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
CGFloat brushSize = 35;
CGColorRef strokeColor = [UIColor clearColor].CGColor;
UITouch *touch = [touches anyObject];
currentTouch = [touch locationInView:bg];
UIGraphicsBeginImageContext(bg.frame.size);
CGContextRef context2 = UIGraphicsGetCurrentContext();
[bg.image drawInRect:CGRectMake(0, 0, bg.frame.size.width, bg.frame.size.height)];
CGContextSetLineCap(context2, kCGLineCapRound);
CGContextSetLineWidth(context2, brushSize);
CGContextSetStrokeColorWithColor(context2, strokeColor);
CGContextSetBlendMode(context2, kCGBlendModeClear);
CGContextBeginPath(context2);
CGContextMoveToPoint(context2, lastTouch.x, lastTouch.y);
CGContextAddLineToPoint(context2, currentTouch.x, currentTouch.y);
CGContextStrokePath(context2);
bg.image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
lastTouch = currentTouch;
}
How should I change my code?
hi i have done getting image from Gallery or camera.and i have button when i click that button getting image again from gallery or camera in which when i touch some part that is highlighting that should be only display in to anotherView.remaing part should be removed.please anybody assist me how to do this.help is appreciated. i written code this
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
self.slider.hidden=NO;
UITouch *touch = [touches anyObject];
lastPoint = [touch locationInView:self.view]; //lastTouch is CGPoint declared globally
}
//#pragma mark - Touch moved mehotd
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [touches anyObject];
currentPoint = [touch locationInView:self.view1]; //currentTouch is CGPoint declared globally
CGColorRef strokeColor = [UIColor whiteColor].CGColor;
UIGraphicsBeginImageContext(view1.frame.size);
CGContextRef context = UIGraphicsGetCurrentContext();
[imageView1.image drawInRect:CGRectMake(0, 0, self.view1.frame.size.width, self.view1.frame.size.height)];
//canvasView is your UIImageView object declared globally
CGContextSetLineCap(context, kCGLineCapRound);
CGContextSetLineWidth(context, slider.value);
CGContextSetStrokeColorWithColor(context, strokeColor);
CGContextSetBlendMode(context, kCGBlendModeClear);
CGContextBeginPath(context);
CGContextMoveToPoint(context, lastPoint.x, lastPoint.y);
CGContextAddLineToPoint(context, currentPoint.x, currentPoint.y);
CGContextStrokePath(context);
imageView1.image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
lastPoint = [touch locationInView:self.view1];
}
//#pragma mark - Touch end mehotd
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [touches anyObject];
currentPoint = [touch locationInView:self.view1];
}
but it is erasing selected Area.but i don't want to erase the selected Area(highlight).unselected part should be erased .i tried a lot please any body reply me how to do this.help is appreciated
your question sounds good. I think somebody already give answer earlier like same query.
Please have a look following
Let User Crop Photo in iOS App
i hope will help you. All the best!! :)
I have implemented the following code which allows the user to draw on an imageView. I would like to implement this throughout my app but would prefer not to keep copying and pasting.
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [touches anyObject];
pointCurrent = [touch locationInView:self.view];
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [touches anyObject];
CGPoint pointNext = [touch locationInView:self.view];
UIGraphicsBeginImageContext(drawImage.frame.size);
[drawImage.image drawInRect:CGRectMake(0, 0, drawImage.frame.size.width, drawImage.frame.size.height)];
CGContextSetLineWidth(UIGraphicsGetCurrentContext(), 2.0);
CGContextSetRGBStrokeColor(UIGraphicsGetCurrentContext(), red, green, 0.0, 1.0);
CGContextMoveToPoint(UIGraphicsGetCurrentContext(), pointCurrent.x, pointCurrent.y);
CGContextAddLineToPoint(UIGraphicsGetCurrentContext(), pointNext.x, pointNext.y);
CGContextStrokePath(UIGraphicsGetCurrentContext());
drawImage.image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
pointCurrent = pointNext;
}
So far I have tried to create a category but I'm unsure if this is the right way to go about it. Do I make a custom method and try to call that in the other classes or am I barking up the wrong tree? Thanks in advance for taking the time to read this question.
I modified your code a little, because I was getting that same error that you mention in your comment. This code worked for me.
#interface RDImageView ()
#property (nonatomic) CGPoint pointCurrent;
#end
#implementation RDImageView
-(instancetype)initWithCoder:(NSCoder *)aDecoder {
if (self = [super initWithCoder:aDecoder]) {
self.userInteractionEnabled = YES;
self.backgroundColor = [UIColor blueColor];
}
return self;
}
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [touches anyObject];
self.pointCurrent = [touch locationInView:self];
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [touches anyObject];
CGPoint pointNext = [touch locationInView:self];
UIGraphicsBeginImageContext(self.frame.size);
[self.image drawInRect:self.bounds];
CGContextSetLineWidth(UIGraphicsGetCurrentContext(), 2.0);
CGContextSetRGBStrokeColor(UIGraphicsGetCurrentContext(), 1,1, 0.0, 1.0);
CGContextMoveToPoint(UIGraphicsGetCurrentContext(), self.pointCurrent.x, self.pointCurrent.y);
CGContextAddLineToPoint(UIGraphicsGetCurrentContext(), pointNext.x, pointNext.y);
CGContextStrokePath(UIGraphicsGetCurrentContext());
self.image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
self.pointCurrent = pointNext;
}
i'm researching on the time it will take and how to make a drawing pad for a elementary school kids. So it will be similar draw something, but only with the draw pad. Kids will be able to change different colors to draw it. So which frameworks should I look at? core graphics? Are there anything else? Can anyone point to a tutorial or directions? Thanks in advance.
Try this code ....
#pragma mark touches stuff...
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [touches anyObject];
lastTouch = [touch locationInView:imageView];
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [touches anyObject];
currentTouch = [touch locationInView:imageView];
CGColorRef strokeColor = [UIColor brownColor].CGColor;
UIGraphicsBeginImageContext(imageView.frame.size);
CGContextRef context = UIGraphicsGetCurrentContext();
[imageView.image drawInRect:CGRectMake(0, 0, imageView.frame.size.width, imageView.frame.size.height)];
CGContextSetLineCap(context, kCGLineCapRound);
CGContextSetLineWidth(context,10); // 10 is the pen size
CGContextSetStrokeColorWithColor(UIGraphicsGetCurrentContext(), [UIColor brownColor].CGColor); // this will be colour u need to change as required
CGContextSetBlendMode(context,kCGBlendModeDarken );
CGContextBeginPath(context);
CGContextMoveToPoint(context, lastTouch.x, lastTouch.y);
CGContextAddLineToPoint(context, currentTouch.x, currentTouch.y);
CGContextStrokePath(context);
imageView.image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
lastTouch = [touch locationInView:imageView];
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [touches anyObject];
lastTouch = [touch locationInView:imageView];
}
I hope this will help you ....
I want to know what's the approach to draw a line with a finger in a white view. I want to do an artboard, and I want begin to understand how draw a simple line or a track done with a finger. How can I do it?
I have understood your problem.
Please see the bellow code.It will use full for you.
-(void)intializeDrawImage
{
drawImage = [[UIImageView alloc]initWithFrame:CGRectMake(0, 100, 320, 320)];
[drawImage setBackgroundColor:[UIColor purpleColor]];
[drawImage setUserInteractionEnabled:YES];
[self.view addSubview:drawImage];
}
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
NSLog(#"touchesBegan");
UITouch *touch = [touches anyObject];
CGPoint p = [touch locationInView:drawImage];
startPoint = p;
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
NSLog(#"touchesMoved");
UITouch *touch = [touches anyObject];
CGPoint p = [touch locationInView:drawImage];
[self drawLineFrom:startPoint endPoint:p];
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
[self touchesMoved:touches withEvent:event];
}
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event
{
[self touchesEnded:touches withEvent:event];
}
-(void)drawLineFrom:(CGPoint)from endPoint:(CGPoint)to
{
drawImage.image = [UIImage imageNamed:#""];
UIGraphicsBeginImageContext(drawImage.frame.size);
[drawImage.image drawInRect:CGRectMake(0, 0, drawImage.frame.size.width, drawImage.frame.size.height)];
[[UIColor greenColor] set];
CGContextSetLineWidth(UIGraphicsGetCurrentContext(), 5.0f);
CGContextMoveToPoint(UIGraphicsGetCurrentContext(), from.x, from.y);
CGContextAddLineToPoint(UIGraphicsGetCurrentContext(), to.x , to.y);
CGContextStrokePath(UIGraphicsGetCurrentContext());
drawImage.image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
}