I have these sizes of circles that changes using a UISlider and draws on touch.
Now, i am trying give it a new style on how it will draw on the screen on touch, and it's like this, when the user holds the touch (for example he's on the middle size circle) it'll start form the smallest size and stops on its current size but when the user just tap the screen very quick it'll just draw the smallest size no matter what's the size is...
how will i able to that??
here's my current code:
On touchesBegan:
if(!touchSwiped) {
UIGraphicsBeginImageContext(self.view.frame.size);
[drawView.image drawInRect:CGRectMake(0, 0, 768, 1024)];
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetLineCap(context, kCGLineCapRound);
CGContextSetLineWidth(context, lineWidth);
CGContextSetRGBStrokeColor(context, color1, color2, color3, alpha);
CGContextSetBlendMode(context, blendMode);
CGContextMoveToPoint(context, endingPoint.x, endingPoint.y);
CGContextAddLineToPoint(context, endingPoint.x, endingPoint.y);
CGContextStrokePath(context);
CGContextFlush(context);
drawView.image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
}
Thanks!
UILongPressGestureRecognizer may be what you're looking for.
Related
I have one UIView in that I have draw image. On this View I am drawing pen tool, rectangle tool and update the new image and draw. Just Like the ACEDrawingView
I am facing one issue with the eraser tool. when I use the eraser the background image color is also gone. Please check the screenshot.
In the above image the black portion is pen drawing and white portion is my eraser drawing. what I want when user do the eraser drawing not to clear the background image. just the drawing.
Redraw Image code
- (void)updateCacheImage:(BOOL)redraw
{
UIGraphicsBeginImageContextWithOptions(self.bounds.size, NO, 0.0);
if (redraw) {
// erase the previous image
self.image = nil;
// load previous image (if returning to screen)
[[self.prev_image copy] drawInRect:CGRectMake(0, 0, self.frame.size.width, self.frame.size.height)];
// I need to redraw all the lines
for (id<ACEDrawingTool> tool in self.pathArray) {
[tool draw];
}
} else {
// set the draw point
[self.image drawAtPoint:CGPointZero];
[self.currentTool draw];
}
// store the image
self.image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
}
Eraser tool drawing
- (void)draw
{
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextAddPath(context, self.path);
CGContextSetLineCap(context, kCGLineCapRound);
CGContextSetLineWidth(context, self.lineWidth);
CGContextSetStrokeColorWithColor(context, self.lineColor.CGColor);
CGContextSetBlendMode(context, kCGBlendModeNormal);
CGContextSetAlpha(context, self.lineAlpha);
CGContextStrokePath(context);
}
This is because you are using self.lineColor.CGColor which i guess is the last chosen color, which is white in this case. Try replacing the current color with [UIColor clearColor] and add this line of code CGContextSetBlendMode(UIGraphicsGetCurrentContext(), kCGBlendModeClear);
I have faced this now ...Just found the solutions like following.Your eraser colour should be like your background view background colour.
example:
CGContextSetStrokeColorWithColor(context, yourviewBackgroundColor);
I have the following code:
- (void)drawRect:(CGRect)rect {
CGContextRef context = UIGraphicsGetCurrentContext();
// Left frame.
CGContextAddRect(context, CGRectMake(0, 0,
frameWidth,
self.frameHeight));
CGContextSetFillColorWithColor(context, [UIColor colorWithRed:frameBorderColorRed
green:frameBorderColorGreen
blue:frameBorderColorBlue
alpha:frameBorderColorAlpha].CGColor);
CGContextFillPath(context);
CGContextAddRect(context, CGRectMake(frameBorderWidth,
frameBorderWidth,
frameWidth - (2*frameBorderWidth),
self.frameHeight - (2*frameBorderWidth)));
CGContextSetBlendMode(context, kCGBlendModeClear);
CGContextFillPath(context);
// Right frame.
CGContextAddRect(context, CGRectMake(frameWidth + distanceBetweenFrames,
0,
frameWidth,
self.frameHeight));
CGContextSetFillColorWithColor(context, [UIColor colorWithRed:frameBorderColorRed
green:frameBorderColorGreen
blue:frameBorderColorBlue
alpha:frameBorderColorAlpha].CGColor);
CGContextFillPath(context);
CGContextAddRect(context, CGRectMake(frameWidth + distanceBetweenFrames + frameBorderWidth,
frameBorderWidth,
frameWidth - (2*frameBorderWidth),
self.frameHeight - (2*frameBorderWidth)));
CGContextSetBlendMode(context, kCGBlendModeClear);
CGContextFillPath(context);
}
The left frame is showing but the right frame isn't. However, if I were to comment out the left frame, the right frame shows. I have also tried drawing the lines themselves as in the docs:
https://developer.apple.com/library/mac/documentation/GraphicsImaging/Reference/CGContext/index.html#//apple_ref/c/func/CGContextAddRect
To no avail.
I would consider using CoreAnimation since it uses GPU.
Besides the problem is that you close current path by:
CGContextFillPath(context);
and then try to use:
CGContextAddRect
As documentation says: "Adds a rectangular path to the current path."
You need to use method below to add another path:
CGContextMoveToPoint
More detailed information you can read there:
https://developer.apple.com/library/mac/documentation/GraphicsImaging/Reference/CGContext/index.html
I am drawing a line using the following method:
- (void)drawLineWithColor:(UIColor *)color andRect: (CGRect)rect{
if (uploadButtonHidden == 2) {
uploadPhotoButton.hidden = NO;
}
UIGraphicsBeginImageContext(rect.size);
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextTranslateCTM(context, 15, 110);
// set the stroke color and width
CGContextSetStrokeColorWithColor(context, [color CGColor]);
CGContextSetLineWidth(context, 6.0);
// move to your first point
CGContextMoveToPoint(context, 455, coords.y - 140);
// add a line to your second point
CGContextAddLineToPoint(context, coordsFinal.x, coordsFinal.y);
// tell the context to draw the stroked line
CGContextStrokePath(context);
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
// Draw image on view
[image drawAtPoint:CGPointZero];
}
As you can see coords.y sets the starting point of my line. Is there any way when changing the coords.y point to update my line? If for example I have a method which adds 50 to coords.y every 0.5 seconds, how can I update the line without redrawing it (to prevent a memory crash)??
EDIT:
this method is called like this:
UIGraphicsBeginImageContext(self.view.frame.size);
[self drawLineWithColor:[UIColor blackColor] andRect:CGRectMake(20, 30, 1476, 1965)];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
imageViewForArrows = [[UIImageView alloc] initWithImage:image];
[imageArrowsArray addObject:imageViewForArrows];
Don't draw into an image, draw straight into the context instead. I'm assuming this method is called from within your drawRect method, in which case there will already be a value CGContextRef. You just have to get it and draw into it. Be sure to use CGContextSaveGState and CGContextRestoreGState when you apply a transform or clipping.
- (void)drawLineWithColor:(UIColor *)color andRect: (CGRect)rect{
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSaveGState(context);
CGContextTranslateCTM(context, 15, 110);
// set the stroke color and width
CGContextSetStrokeColorWithColor(context, [color CGColor]);
CGContextSetLineWidth(context, 6.0);
// move to your first point
CGContextMoveToPoint(context, 455, coords.y - 140);
// add a line to your second point
CGContextAddLineToPoint(context, coordsFinal.x, coordsFinal.y);
// tell the context to draw the stroked line
CGContextStrokePath(context);
CGContextRestoreGState(context);
}
I'm having some issues while trying to draw lines smoothly on touches moved when my UIView is zoomed in. The thing is that lines start to look very pixelated upon certain zoom level.
My view hierarchy is really simple as of now, since this is more like a proof of concept. I have a UIScrollView, my UIView as a child and also it is set as the zoom view.
My drawRect: implementation looks like this:
CGContextRef context = UIGraphicsGetCurrentContext();
[self.layer renderInContext:context];
CGPoint mid1 = midPoint(_previousPoint1, _previousPoint2);
CGPoint mid2 = midPoint(_currentPoint, _previousPoint1);
CGContextSetBlendMode(context, kCGBlendModeNormal);
CGContextMoveToPoint(context, mid1.x, mid1.y);
CGContextAddQuadCurveToPoint(context, _previousPoint1.x, _previousPoint1.y, mid2.x, mid2.y);
CGContextSetLineCap(context, kCGLineCapRound);
CGContextSetLineJoin(context, kCGLineJoinRound);
CGContextSetLineWidth(context, self.lineWidth);
CGContextSetStrokeColorWithColor(context, self.lineColor.CGColor);
CGContextStrokePath(context);
Dumping the contents of the layer into the context is an important part since I'm only refreshing the bounding box enclosing the path formed by the last three touched points (_previousPoint1, _previousPoint2 and _currentPoint).
That operation is actually done on touchesMoved method and the function that handles it is the following:
- (void)calculateMinImageArea:(CGPoint)pp1 :(CGPoint)pp2 :(CGPoint)cp
{
// calculate mid point
CGPoint mid1 = midPoint(pp1, pp2);
CGPoint mid2 = midPoint(cp, pp1);
CGMutablePathRef path = CGPathCreateMutable();
CGPathMoveToPoint(path, NULL, mid1.x, mid1.y);
CGPathAddQuadCurveToPoint(path, NULL, pp1.x, pp1.y, mid2.x, mid2.y);
CGRect bounds = CGPathGetBoundingBox(path);
CGPathRelease(path);
CGRect drawBox = [self extendedRect:bounds];
UIGraphicsBeginImageContext(drawBox.size);
[self.layer renderInContext:UIGraphicsGetCurrentContext()];
UIGraphicsEndImageContext();
[self setNeedsDisplayInRect:drawBox];
}
I was able to find a workaround using CAShapeLayers to draw the paths. However, the low performance wasn't acceptable.
I would really appreciate if someone can point me to the right approach.
Thanks.
[self setContentScaleFactor:scale];
use this in scrollViewDidEndZooming: delegate method
Hope this help's you
I am trying to make a line graph using the drawRect method but I have came across a major problem. The 0 point on the iPhone screen is in the top left corner. Is there any way to either relocate the 0,0 point or change the coordinates input to where they would be if the 0,0 point was in the bottom left corner?
Heres My drawRect method
- (void)drawRect:(CGRect)rect
{
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetLineWidth(context, 1.0);
CGColorSpaceRef colorspace = CGColorSpaceCreateDeviceRGB();
CGFloat components[] = {0.0, 0.0, 1.0, 1.0};
CGColorRef color = CGColorCreate(colorspace, components);
CGContextSetStrokeColorWithColor(context, [UIColor blackColor].CGColor);
//Coordinates of bottom left corner (480 went off screen)
CGContextMoveToPoint(context, 0, 460);
CGContextAddLineToPoint(context, 320, 0);
CGContextStrokePath(context);
CGColorSpaceRelease(colorspace);
CGColorRelease(color);
}
This page describes how to treat it as a right-hand coordinate system instead of a left-hand, which sounds like what you want