I am following this tutorial for my doodle application.
http://www.raywenderlich.com/18840/how-to-make-a-simple-drawing-app-with-uikit
his erase function is using white color drawing. But I am using image background and when I erase, I really need to erase.
I have tried
CGContextSetBlendMode(UIGraphicsGetCurrentContext(), kCGBlendModeClear);
But it's not working. Here is my code:
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
_mouseSwiped = NO;
UITouch *touch = [touches anyObject];
_lastPoint = [touch locationInView:self.tempImageView];
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
_mouseSwiped = YES;
UITouch *touch = [touches anyObject];
CGPoint currentPoint = [touch locationInView:self.tempImageView];
UIGraphicsBeginImageContext(self.tempImageView.frame.size);
[self.tempImageView.image drawInRect:CGRectMake(0, 0, self.tempImageView.frame.size.width, self.tempImageView.frame.size.height)];
CGContextMoveToPoint(UIGraphicsGetCurrentContext(), _lastPoint.x, _lastPoint.y);
CGContextAddLineToPoint(UIGraphicsGetCurrentContext(), currentPoint.x, currentPoint.y);
CGContextSetLineCap(UIGraphicsGetCurrentContext(), kCGLineCapRound);
CGContextSetLineWidth(UIGraphicsGetCurrentContext(), _width );
CGContextSetRGBStrokeColor(UIGraphicsGetCurrentContext(), _red, _green, _blue, 1.0);
if (_isErasing) {
CGContextSetBlendMode(UIGraphicsGetCurrentContext(), kCGBlendModeClear);
}
else {
CGContextSetBlendMode(UIGraphicsGetCurrentContext(),kCGBlendModeNormal);
}
CGContextStrokePath(UIGraphicsGetCurrentContext());
self.tempImageView.image = UIGraphicsGetImageFromCurrentImageContext();
[self.tempImageView setAlpha:_alpha];
UIGraphicsEndImageContext();
_lastPoint = currentPoint;
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
CGSize size = self.tempImageView.frame.size;
if(!_mouseSwiped) {
UIGraphicsBeginImageContext(self.tempImageView.frame.size);
[self.tempImageView.image drawInRect:CGRectMake(0, 0, size.width, size.height)];
CGContextSetLineCap(UIGraphicsGetCurrentContext(), kCGLineCapRound);
CGContextSetLineWidth(UIGraphicsGetCurrentContext(), _width);
CGContextSetRGBStrokeColor(UIGraphicsGetCurrentContext(), _red, _green, _blue, _alpha);
CGContextMoveToPoint(UIGraphicsGetCurrentContext(), _lastPoint.x, _lastPoint.y);
CGContextAddLineToPoint(UIGraphicsGetCurrentContext(), _lastPoint.x, _lastPoint.y);
CGContextStrokePath(UIGraphicsGetCurrentContext());
CGContextFlush(UIGraphicsGetCurrentContext());
self.tempImageView.image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
}
UIGraphicsBeginImageContext(self.drawImageView.frame.size);
[self.drawImageView.image drawInRect:CGRectMake(0, 0, size.width, size.height) blendMode:kCGBlendModeNormal alpha:1.0];
if (_isErasing) {
CGContextSetBlendMode(UIGraphicsGetCurrentContext(), kCGBlendModeClear);
}
[self.tempImageView.image drawInRect:CGRectMake(0, 0, self.tempImageView.frame.size.width, self.tempImageView.frame.size.height) blendMode:kCGBlendModeNormal alpha:_alpha];
self.drawImageView.image = UIGraphicsGetImageFromCurrentImageContext();
self.tempImageView.image = nil;
UIGraphicsEndImageContext();
}
iOS includes the Core Graphics framework to provide low-level drawing support. These frameworks are what enable the rich graphical capabilities within UIKit. Core Graphics is a low-level 2D graphics framework that allows drawing device independent graphics. All 2D drawing in UIKit uses Core Graphics internally.
Handle path-based drawing, antialiased rendering, gradients, images, color management, PDF documents, and more. The Core Graphics framework is based on the Quartz advanced drawing engine. It provides low-level, lightweight 2D rendering with unmatched output fidelity.
In iOS, all drawing to the screen—regardless of whether it involves OpenGL, Quartz, UIKit, or Core Animation—occurs within the confines of an instance of the UIView class or a subclass thereof. Views define the portion of the screen in which drawing occurs. If you use system-provided views, this drawing is handled for you automatically.
As with paths and images, drawing text with Core Graphics involves the same basic pattern of setting some graphics state and calling a method to draw. In the case of text, the method to display text is ShowText. When added to the image drawing example, the following code draws some text using Core Graphics:
solved this problem by swapping tempImageView and drawImageView when touch began if it's erasing
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
_mouseSwiped = NO;
UITouch *touch = [touches anyObject];
_lastPoint = [touch locationInView:self.tempImageView];
if (_isErasing) {
self.tempImageView.image = self.drawImageView.image;
self.drawImageView.image = nil;
}
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
_mouseSwiped = YES;
UITouch *touch = [touches anyObject];
CGPoint currentPoint = [touch locationInView:self.tempImageView];
UIGraphicsBeginImageContext(self.tempImageView.frame.size);
[self.tempImageView.image drawInRect:CGRectMake(0, 0, self.tempImageView.frame.size.width, self.tempImageView.frame.size.height)];
CGContextMoveToPoint(UIGraphicsGetCurrentContext(), _lastPoint.x, _lastPoint.y);
CGContextAddLineToPoint(UIGraphicsGetCurrentContext(), currentPoint.x, currentPoint.y);
CGContextSetLineCap(UIGraphicsGetCurrentContext(), kCGLineCapRound);
CGContextSetLineWidth(UIGraphicsGetCurrentContext(), _width );
if (_isErasing) {
CGContextSetBlendMode(UIGraphicsGetCurrentContext(), kCGBlendModeClear);
}
else {
CGContextSetRGBStrokeColor(UIGraphicsGetCurrentContext(), _red, _green, _blue, 1.0);
CGContextSetBlendMode(UIGraphicsGetCurrentContext(),kCGBlendModeNormal);
}
CGContextStrokePath(UIGraphicsGetCurrentContext());
self.tempImageView.image = UIGraphicsGetImageFromCurrentImageContext();
[self.tempImageView setAlpha:_alpha];
UIGraphicsEndImageContext();
_lastPoint = currentPoint;
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
CGSize size = self.tempImageView.frame.size;
if(!_mouseSwiped) {
UIGraphicsBeginImageContext(self.tempImageView.frame.size);
[self.tempImageView.image drawInRect:CGRectMake(0, 0, size.width, size.height)];
CGContextSetLineCap(UIGraphicsGetCurrentContext(), kCGLineCapRound);
CGContextSetLineWidth(UIGraphicsGetCurrentContext(), _width);
if (_isErasing) {
CGContextSetBlendMode(UIGraphicsGetCurrentContext(), kCGBlendModeClear);
}
else {
CGContextSetRGBStrokeColor(UIGraphicsGetCurrentContext(), _red, _green, _blue, _alpha);
CGContextSetBlendMode(UIGraphicsGetCurrentContext(),kCGBlendModeNormal);
}
CGContextMoveToPoint(UIGraphicsGetCurrentContext(), _lastPoint.x, _lastPoint.y);
CGContextAddLineToPoint(UIGraphicsGetCurrentContext(), _lastPoint.x, _lastPoint.y);
CGContextStrokePath(UIGraphicsGetCurrentContext());
CGContextFlush(UIGraphicsGetCurrentContext());
self.tempImageView.image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
}
UIGraphicsBeginImageContext(self.drawImageView.frame.size);
[self.drawImageView.image drawInRect:CGRectMake(0, 0, size.width, size.height) blendMode:kCGBlendModeNormal alpha:1.0];
[self.tempImageView.image drawInRect:CGRectMake(0, 0, size.width, size.height) blendMode:kCGBlendModeNormal alpha:_alpha];
self.drawImageView.image = UIGraphicsGetImageFromCurrentImageContext();
self.tempImageView.image = nil;
UIGraphicsEndImageContext();
}
If anybody is still intereted this is how it worked for me in Swift 3. Thanks for the help OMGPOP
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
swiped = false
hideAllButtons()
if let touch = touches.first {
lastPoint = touch.location(in: self.view)
}
if isErasing {
self.tempImageView.image = self.mainImageView.image
self.mainImageView.image = nil
}
}
override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
swiped = true
if let touch = touches.first {
let currentPoint = touch.location(in: view)
drawLineFrom(fromPoint: lastPoint, toPoint: currentPoint)
lastPoint = currentPoint
}
}
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
showAllButtons()
if !swiped {
drawLineFrom(fromPoint: lastPoint, toPoint: lastPoint)
}
UIGraphicsBeginImageContext(mainImageView.frame.size)
mainImageView.image?.draw(in: CGRect(x: 0, y: 0, width: view.frame.size.width, height: view.frame.size.height), blendMode: .normal, alpha: 1.0)
tempImageView.image?.draw(in: CGRect(x: 0, y: 0, width: view.frame.size.width, height: view.frame.size.height), blendMode: .normal, alpha: opacity)
mainImageView.image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
tempImageView.image = nil
}
// Draws a line between two points on the view
func drawLineFrom(fromPoint: CGPoint, toPoint: CGPoint) {
UIGraphicsBeginImageContext(view.frame.size)
let context = UIGraphicsGetCurrentContext()
tempImageView.image?.draw(in: CGRect(x:0, y:0, width: view.frame.size.width, height: view.frame.size.height))
context?.move(to: fromPoint)
context?.addLine(to: toPoint)
context?.setLineCap(.round)
context?.setLineWidth(brushWidth)
if isErasing {
context?.setBlendMode(.clear)
} else {
context?.setStrokeColor(red: red, green: green, blue: blue, alpha: 1.0)
context?.setBlendMode(.normal)
}
context?.strokePath()
tempImageView.image = UIGraphicsGetImageFromCurrentImageContext()
tempImageView.alpha = opacity
UIGraphicsEndImageContext()
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With