No se puede incluir deshacer / rehacer con un dibujo suave a mano libre

Luchando con el tema desde hace muchos días. Espero que pueda obtener una respuesta aquí. he utilizadoesta Enlace para suavizar mi dibujo a mano libre. En este código pude establecer el ancho y el color de la línea, pero me resulta muy difícil cuando trato de incluir la función de deshacer / rehacer usandoesta enlace que funciona bien al deshacer rehacer, pero su mano libre no es suave.

Después de un poco de investigación y codificación, debo saber que es el diseño del dibujo, que creo que impide el deshacer / rehacer.

En el primer enlace hay un archivo "CachedLIView.h / m" cuando utilicé esto e intenté incluir deshacer / rehacer en este, encontré que en el siguiente método:

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event // (2)
{
    UITouch *touch = [touches anyObject];
    CGPoint p = [touch locationInView:self];
    [path addLineToPoint:p];

    [self drawBitmap]; // (3)
    [self setNeedsDisplay];

    [path removeAllPoints]; //(4)
}

este método se llama drawBitMap: método que en realidad genera una imagen temporal cada vez que el usuario levanta el dedo y al mismo tiempo elimina puntos del "camino".

- (void)drawBitmap // (3)
{
    UIGraphicsBeginImageContextWithOptions(self.bounds.size, YES, 0.0);
    [[UIColor blackColor] setStroke];
    if (!incrementalImage) // first draw; paint background white by ...
    {
        UIBezierPath *rectpath = [UIBezierPath bezierPathWithRect:self.bounds]; // enclosing bitmap by a rectangle defined by another UIBezierPath object
        [[UIColor greenColor] setFill];
        [rectpath fill]; // filling it with white
    }
    [incrementalImage drawAtPoint:CGPointZero];
    //[path stroke];
    for (UIBezierPath *_path in pathArray)
        [_path strokeWithBlendMode:kCGBlendModeNormal alpha:1.0];
    incrementalImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
}

Estoy guardando todas las rutas en una matriz para poder deshacer / rehacer. (Tomé esta idea del segundo enlace).

A continuación se muestra el código completo de este archivo que he modificado para incluir deshacer / rehacer:

    #import "CachedLIView.h"

@implementation CachedLIView
{
    UIBezierPath *path;
    UIImage *incrementalImage; // (1)
}

- (id)initWithFrame:(CGRect)frame // (1)
{
    if (self = [super initWithFrame:frame])
    {
        [self setMultipleTouchEnabled:NO]; // (2)
        //        [self setBackgroundColor:[UIColor whiteColor]];
//                path = [[UIBezierPath alloc] init];
//                [path setLineWidth:3];

        pathArray=[[NSMutableArray alloc]init];
        bufferArray=[[NSMutableArray alloc]init];
        [self drawBitmap];
    }
    return self;
}

- (void)drawRect:(CGRect)rect
{
    NSLog(@"in drawrect pathArray[count]: %d", pathArray.count);

    [incrementalImage drawInRect:rect]; // (3)

    //[[UIColor blackColor] setStroke];
    //[path stroke];
    for (UIBezierPath *_path in pathArray)
        [_path strokeWithBlendMode:kCGBlendModeNormal alpha:1.0];
}


- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    path = [[UIBezierPath alloc] init];
    path.lineWidth = 3;

    UITouch *touch = [touches anyObject];
    CGPoint p = [touch locationInView:self];
    [path moveToPoint:p];

    [pathArray addObject:path];

}

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
    UITouch *touch = [touches anyObject];
    CGPoint p = [touch locationInView:self];
    [path addLineToPoint:p];


    [self setNeedsDisplay];
}

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event // (2)
{
    UITouch *touch = [touches anyObject];
    CGPoint p = [touch locationInView:self];
    [path addLineToPoint:p];

    [self drawBitmap]; // (3)
    [self setNeedsDisplay];

    [path removeAllPoints]; //(4)
}

- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event
{
    [self touchesEnded:touches withEvent:event];
}

- (void)drawBitmap // (3)
{
    UIGraphicsBeginImageContextWithOptions(self.bounds.size, YES, 0.0);
    [[UIColor blackColor] setStroke];
    if (!incrementalImage) // first draw; paint background white by ...
    {
        UIBezierPath *rectpath = [UIBezierPath bezierPathWithRect:self.bounds]; // enclosing bitmap by a rectangle defined by another UIBezierPath object
        [[UIColor greenColor] setFill];
        [rectpath fill]; // filling it with white
    }
    [incrementalImage drawAtPoint:CGPointZero];
    //[path stroke];
    for (UIBezierPath *_path in pathArray)
        [_path strokeWithBlendMode:kCGBlendModeNormal alpha:1.0];
    incrementalImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
}

#pragma mark - undo/redo
-(void)undoButtonClicked
{
    if([pathArray count]>0){
        UIBezierPath *_path=[pathArray lastObject];
        [bufferArray addObject:_path];
        [pathArray removeLastObject];

        [self drawBitmap];
        [self setNeedsDisplay];
    }
}

-(void)redoButtonClicked
{
    if([bufferArray count]>0){
        UIBezierPath *_path=[bufferArray lastObject];
        [pathArray addObject:_path];
        [bufferArray removeLastObject];

        [self drawBitmap];
        [self setNeedsDisplay];
    }
}
@end

El archivo .h es:

#import <UIKit/UIKit.h>

@interface CachedLIView : UIView
{
    NSMutableArray *pathArray;
    NSMutableArray *bufferArray;
    UIBezierPath *myPath;

}
-(void)undoButtonClicked;
-(void)redoButtonClicked;
@end

Por favor, ayúdame. Que estoy haciendo mal. El conteo de pathArray está funcionando correctamente. pero no puede mostrar el efecto deshacer / rehacer en la pantalla.

Respuestas a la pregunta(2)

Su respuesta a la pregunta