I am working with unod redo operations on CgLayer, I have tried some code, but not able to get it working, dont know , where I am getting wrong, below is my code, which i have written
this is my drawRect function
- (void)drawRect:(CGRect)rect
{
m_backgroundImage = [UIImage imageNamed:@"bridge.jpg"];
CGPoint drawingTargetPoint = CGPointMake(0,0);
[m_backgroundImage drawAtPoint:drawingTargetPoint];
switch(drawStep)
{
case DRAW:
{
CGContextRef context = UIGraphicsGetCurrentContext();
if(myLayerRef == nil)
{
myLayerRef = CGLayerCreateWithContext(context, self.bounds.size, NULL);
}
CGContextDrawLayerAtPoint(context, CGPointZero, myLayerRef);
break;
}
case UNDO:
{
[curImage drawInRect:self.bounds];
break;
}
default:
break;
}
}
On touches ended , I am converting the layer into NSValue and storing as keyValue pair into NSDictionary and then adding the dictionary object to array.
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
NSValue *layerCopy = [NSValue valueWithPointer:myLayerRef];
NSDictionary *lineInfo = [NSDictionary dictionaryWithObjectsAndKeys:layerCopy, @"IMAGE",
nil];
[m_pathArray addObject:lineInfo];
NSLog(@"%i",[m_pathArray count]);
}
below is my Undo functionality
- (void)undoButtonClicked
{
if([m_pathArray count]>0)
{
NSMutableArray *_line=[m_pathArray lastObject];
[m_bufferArray addObject:[_line copy]];
[m_pathArray removeLastObject];
drawStep = UNDO;
[self redrawLine];
}
}
//Redraw functions
- (void)redrawLine
{
NSDictionary *lineInfo = [m_pathArray lastObject];
NSValue *val = [lineInfo valueForKey:@"IMAGE"];
CGLayerRef layerToShow = (CGLayerRef) [val pointerValue];
CGContextRef context1 = CGLayerGetContext(layerToShow);
CGContextDrawLayerAtPoint(context1, CGPointMake(00, 00),layerToShow);
[self setNeedsDisplayInRect:self.bounds];
}
I think its here where I am goin wrong. So friends please help me out.
From the comments below, I have added the function, where its draws into Cglayer(this function I am calling into touchesMovedEvent.
- (void) drawingOperations
{
CGContextRef context1 = CGLayerGetContext(myLayerRef);
CGPoint mid1 = midPoint(m_previousPoint1, m_previousPoint2);
CGPoint mid2 = midPoint(m_currentPoint, m_previousPoint1);
CGContextMoveToPoint(context1, mid1.x, mid1.y);
CGContextAddQuadCurveToPoint(context1, m_previousPoint1.x, m_previousPoint1.y, mid2.x, mid2.y);
CGContextSetLineCap(context1, kCGLineCapRound);
CGContextSetLineWidth(context1, self.lineWidth);
CGContextSetStrokeColorWithColor(context1, self.lineColor.CGColor);
CGContextSetAllowsAntialiasing(context1, YES);
CGContextSetInterpolationQuality(context1, kCGInterpolationHigh);
CGContextSetAlpha(context1, self.lineAlpha);
CGContextStrokePath(context1);
}
Regards Ranjit
(void)redrawLine { NSDictionary *lineInfo = [m_pathArray lastObject];
NSValue *val = [lineInfo valueForKey:@"IMAGE"];
CGContextRef context1 = (CGContextRef) [val pointerValue]; CGContextDrawLayerAtPoint(context1, CGPointMake(00, 00),layerToShow); [self setNeedsDisplayInRect:self.bounds]; }
just update this method with ur code
The best way to implement Undo and Redo is to implement
NSUndoManager
as a brief description of it you don't have to save each state of Object that you want to undo or redo the NSUndoManager itself make this for you ...Steps for reaching this is:
1- Initialize NSUndoManager.
2- Register Object state in the NSUndoManager object with specified function call will discuss this for you case later.
3-use undo or redo or clear actions function in NSUndoManager Object.
Ex from my working solution
-in .h file
in .m file
@synthesize undoManager;
in "viewDidLoad" method -- initialize your NSUndoManager
undoManager = [[NSUndoManager alloc] init];
Suppose that you have a function in your class that zoom in/out using pinch so in your "viewDidLoad" you will have
So pinch will zoom in/out such Note that "MyImageView" is the image that we want to zoom in/out
-AddImage Function will save current image transformation state in NSUndoManager.
So if you have button that make Undo action
So if you want to cancel all action you have both ways
OR