I'm trying to implement a freehand drawing tool by which user can draw several shapes dynamically like rectangle,eclipse,circle etc on a PDF using touch begins and touch move methods.
So anyone there who have done this kind of tool or have knowledge how to accomplish this,please help me out.
Thank you in advance.
This is a very broad question to be answered on StackOverflow. Still I am trying to give you a start here.
1) Declare two global variables BOOL mouseSwiped, CGPoint lastPoint in your UIViewController.
2)
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
mouseSwiped = NO;
UITouch *touch = [touches anyObject];
lastPoint = [touch locationInView:self.view];
}
3)
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
mouseSwiped = YES;
UITouch *touch = [touches anyObject];
CGPoint currentPoint = [touch locationInView:self.view];
UIGraphicsBeginImageContext(yourSubview.frame.size);
[yourSubview drawInRect:CGRectMake(0, 0, yourSubview.frame.size.width, yourSubview.frame.size.height)];
CGContextMoveToPoint(UIGraphicsGetCurrentContext(), lastPoint.x, lastPoint.y);
CGContextAddLineToPoint(UIGraphicsGetCurrentContext(), currentPoint.x, currentPoint.y);
CGContextSetLineCap(UIGraphicsGetCurrentContext(), kCGLineCapRound);
CGContextSetLineWidth(UIGraphicsGetCurrentContext(), 3.0 );
CGContextSetRGBStrokeColor(UIGraphicsGetCurrentContext(), red, green, blue, 1.0);
CGContextSetBlendMode(UIGraphicsGetCurrentContext(),kCGBlendModeNormal);
CGContextStrokePath(UIGraphicsGetCurrentContext());
yourSubview = UIGraphicsGetImageFromCurrentImageContext();
[yourSubview setAlpha:1.0];
UIGraphicsEndImageContext();
lastPoint = currentPoint;
}
4)
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
UIGraphicsBeginImageContext(yourSubview.frame.size);
[yourSubview drawInRect:CGRectMake(0, 0, yourSubview.frame.size.width, yourSubview) blendMode:kCGBlendModeNormal alpha:1.0];
yourSubview = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
}
Hope this helps
Related
I display a popover that's allows to draw inside.
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
mouseSwiped = NO;
UITouch *touch = [touches anyObject];
lastPoint = [touch locationInView:self.view];
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
mouseSwiped = YES;
UITouch *touch = [touches anyObject];
CGPoint currentPoint = [touch locationInView:self.view];
NSLog(#"lastPoint: %#", NSStringFromCGPoint(lastPoint));
UIGraphicsBeginImageContext(self.view.frame.size);
[mainImage.image drawInRect:CGRectMake(0, 0, 600, 400)];
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());
mainImage.image = UIGraphicsGetImageFromCurrentImageContext();
[mainImage setAlpha:opacity];
UIGraphicsEndImageContext();
lastPoint = currentPoint;
}
My problem is that since the iOS13, it doesn't display well.
How it should display:
How it display now in iOS13:
Any ideas?
what i have done is getting image from gallery which should
be erased while moving finger on image using touch.my image is erasing.but problem is app terminates when erasing the image .my code is like this
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
self.sizeSlider.hidden=NO;
UITouch *touch = [touches anyObject];
lastPoint = [touch locationInView:self.view];
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [touches anyObject];
CGPoint currentPoint = [touch locationInView:self.shareView];
UIGraphicsBeginImageContext(self.shareView.frame.size);
[imgForeGround.image drawInRect:CGRectMake(0, 0, self.shareView.frame.size.width,
self.shareView.frame.size.height)];
// I add this
CGContextSetBlendMode(UIGraphicsGetCurrentContext(), kCGBlendModeClear);
CGContextSetLineCap(UIGraphicsGetCurrentContext(), kCGLineCapRound);
CGContextSetLineWidth(UIGraphicsGetCurrentContext(), sizeSlider.value);
CGContextBeginPath(UIGraphicsGetCurrentContext());
CGContextSetBlendMode(UIGraphicsGetCurrentContext(), kCGBlendModeClear);
CGContextMoveToPoint(UIGraphicsGetCurrentContext(), lastPoint.x, lastPoint.y);
CGContextAddLineToPoint(UIGraphicsGetCurrentContext(), currentPoint.x, currentPoint.y);
CGContextStrokePath(UIGraphicsGetCurrentContext());
imgForeGround.image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
lastPoint = currentPoint;
[imgForeGround setNeedsDisplay];
}
please anybody help me to avoid this memory leaks of this problem help is appreciated
There are few more controls easy to implement:
https://github.com/moqod/iOS-Scratch-n-See
I'm trying to add a drawing functionality using touch events on my UIImage (inside a UIImageView). However, for certain images, when I begin drawing, the image starts shrinking and becomes blurier the more i draw on it. I mostly used ray wenderlich's old drawing tutorial for reference, just changed values to match my UI. The two images show you what happens when i draw:
It looks like I'm using pretty standard methods for the drawing. My hunch is that the bounds/rectangle drawing methods are causing some sort of problem.
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
if(_allowDoodling == NO) return;
UITouch *touch = [touches anyObject];
lastPoint = [touch previousLocationInView:self.imageView];
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
if(_allowDoodling == NO) return;
UITouch *touch = [touches anyObject];
CGPoint currentPoint = [touch locationInView:self.imageView];
UIGraphicsBeginImageContextWithOptions(_imageView.frame.size, NO, 2.0f);
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetInterpolationQuality(context, kCGInterpolationHigh);
[_imageView.image drawInRect:_imageView.bounds];
CGContextMoveToPoint(UIGraphicsGetCurrentContext(), lastPoint.x, lastPoint.y);
CGContextAddLineToPoint(context, currentPoint.x, currentPoint.y);
CGContextSetLineCap(context, kCGLineCapRound);
CGContextSetLineWidth(context, 5.0);
CGContextSetStrokeColorWithColor(context, _doodleColor.CGColor);
CGContextStrokePath(UIGraphicsGetCurrentContext());
_imageView.image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
lastPoint = currentPoint;
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
if(_allowDoodling == NO) return;
UIGraphicsBeginImageContextWithOptions(_imageView.frame.size, NO, 2.0f);
[_imageView.image drawInRect:_imageView.bounds];
_imageView.image = UIGraphicsGetImageFromCurrentImageContext();
CGContextFlush(UIGraphicsGetCurrentContext());
UIGraphicsEndImageContext();
}
It posible, that you have to use
UIGraphicsBeginImageContextWithOptions(CGSizeMake(_imageView.frame.size.width * 2, _imageView.frame.size.width * 2), NO, 1.0f);
I have created a drawing app to draw when you touch the screen and it works very smooth in the simulator but when I tested it on my iPad 2 it slows down and it takes very long time to draw I am using these lines of code:
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [[event allTouches] anyObject];
lastPoint = [touch locationInView:self.view];
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
mouseSwiped = YES;
UITouch *touch = [touches anyObject];
currentPoint = [touch locationInView:self.view];
UIGraphicsBeginImageContext(self.view.frame.size);
[drawImage.image drawInRect:self.view.frame];
CGContextSetLineCap(UIGraphicsGetCurrentContext(), kCGLineCapRound);
CGContextSetLineWidth(UIGraphicsGetCurrentContext(), 7.0);
CGContextSetRGBStrokeColor(UIGraphicsGetCurrentContext(), 0, 1, 0, 1);
CGContextBeginPath(UIGraphicsGetCurrentContext());
CGContextMoveToPoint(UIGraphicsGetCurrentContext(), lastPoint.x, lastPoint.y);
CGContextAddLineToPoint(UIGraphicsGetCurrentContext(), currentPoint.x, currentPoint.y);
CGContextStrokePath(UIGraphicsGetCurrentContext());
[drawImage setFrame:self.view.frame];
drawImage.image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
lastPoint = currentPoint;
[self.view addSubview:drawImage];
}
I think the problem is with calling drawInRect: method in touchMoved: method
Build up a UIBezierPath in your touchesMoved and don't do any drawing there.
Call setNeedsDisplay in touchesMoved.
Override drawRect and draw your path there.
OR
Use set the layer backing for your view to a CAShapeLayer and add the points to the layer in touchesMoved.
I am new to iOS and building a paint application.
Everything goes ok..but I am unable to implement NSUndoManager in my application for undo and redo purpose.
The problem is that I am unable to store the previous state of painting for undo.
Here is the code
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
mouseSwiped = NO;
UITouch *touch = [touches anyObject];
lastPoint = [touch locationInView:self.tempDrawImage];
[[self.undoManage prepareWithInvocationTarget:self]
touchesMoved:touches withEvent:event];
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
mouseSwiped = YES;
UITouch *touch = [touches anyObject];
CGPoint currentPoint = [touch locationInView:self.tempDrawImage];
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;
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
UIGraphicsBeginImageContext(self.tempDrawImage.frame.size);
[self.tempDrawImage.image drawInRect:
CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height)
blendMode:kCGBlendModeNormal alpha:1.0];
self.tempDrawImage.image = UIGraphicsGetImageFromCurrentImageContext();
[[self.undoManage prepareWithInvocationTarget:self] touchesMoved:touches
withEvent:event];
UIGraphicsEndImageContext();
}
-(void)undo
{
[self.undoManage undo];
}
-(void)redo
{
[self.undoManage redo];
}