iOS创建CAShapeLayer掩码的反向

5

我是一位新手iOS开发人员,正在开发一款iOS绘图应用程序,该应用程序使用x/y坐标和时间戳播放用户的草图。为了绘制简单的笔画事件,我有一个作为绘图视图的UIView,并使用CAShapeLayers在视图上绘制,代码如下:

if (index == 0){
    CGPathMoveToPoint(path, NULL, point.x, point.y);
} else {
    CGPathAddLineToPoint(path, NULL, point.x, point.y);
}

……

CAShapeLayer *permLayer = [CAShapeLayer layer];
        [permLayer setFrame:CGRectMake(0, 0, 1024, 640)];
        [permLayer setFillColor:[[UIColor clearColor] CGColor]];
        [permLayer setStrokeColor:currentColor.CGColor];
        [permLayer setLineWidth:[event[@"strokeWeight"] floatValue]];
        [permLayer setLineJoin:kCALineJoinRound];
        [permLayer setLineCap:kCALineCapRound];

……

[[self layer] addSublayer:permLayer];

……

一切都很好,看起来很不错:

enter image description here

现在我想要的是一个擦除事件,如下图所示:

enter image description here

我尝试使用另一个CAShapeLayer作为蒙版,并将擦除事件的CGPath绘制到该蒙版中来实现这一点。然而,最终结果与我的期望相反:

enter image description here

我猜我需要以某种方式获取由擦除事件的CGPath创建的CAShapeLayer的反向蒙版?我不确定应该采用什么正确的方法来解决这个问题,因为我不熟悉涉及的大量数学知识。 另一个注意点是,这个动画与CADisplayLink相关联,因此这些绘图动画非常频繁地被刷新,性能非常重要。我之前尝试过将其绘制到UIImages上,而不是CAShapeLayers,并使用kCGBlendModeClear来实现擦除效果,但性能非常差。感谢任何建议或见解!

为什么不从“全开”掩码开始擦除,而不是在其上绘制? - Rhythmic Fistman
因为有背景图片。 - Maksim
我知道这篇文章已经有一段时间了,但是你是否找到了基于CAShapeLayer的擦除解决方案(与背景图像兼容)? - joshs
2个回答

3
我猜我需要以某种方式获取由擦除事件的CGPath创建的CAShapeLayer的反向遮罩层?
所谓的“反向遮罩层”不能用一个CAShapeLayer来描述(至少没有直接的解决方案)。如果你想使用CAShapeLayer,可以通过将“擦除路径”添加到图像的背景色中来实现。
但是,如果我正确理解你的实现,我看到另一个问题:你为每个用户进行的笔画添加了一个子层。如果用户绘制复杂的图片,带有许多笔划,你最终会得到一个巨大的层堆栈,这肯定会导致性能问题。
我建议采用另一种方法,即绘制到图像缓冲区。听起来你尝试过,但由于性能原因而放弃了这种方法 - 但如果正确地完成,性能是相当不错的。
使用以下代码创建自己的位图上下文
_context = CGBitmapContextCreate(...);

在您的touchesBegan/Moved方法中通过以下方式绘制到该上下文中:
if(isEraseEvent)
  CGContextSetBlendMode(_context, kCGBlendModeClear);
else
  CGContextSetBlendMode(_context, kCGBlendModeNormal);

// Configure your current stroke: lineWidth, color etc.
CGContextSetLineWidth(_context, _currentStroke.lineWidth);

// Added stroke from point p to point q
CGContextMoveToPoint(_context, p.x, p.y);
CGContextAddLineToPoint(_context, q.x, q.y);
CGContextStrokePath(_context);

在每个事件之后,显示上下文。你可以将整个上下文呈现为UIImage并显示UIImage,但这样可能会影响性能。相反,让CALayer代理处理渲染。让代理实现该方法。

- (void)drawLayer:(CALayer *)layer inContext:(CGContextRef)ctx {
  CGImageRef tempImage = CGBitmapContextCreateImage(_context);
  CGContextDrawImage(ctx, self.bounds, tempImage);
  CGImageRelease(tempImage);
}

不要忘记在绘制上下文时告诉图层其内容已更改。调用setNeedsDisplay会重新显示整个图层,这通常比你需要的多得多。相反,可以像这样进行操作:

CGRect r = CGRectMake(MIN(p.x, q.x),
                    MIN(p.y, q.y),
                    ABS(p.x-q.x),
                    ABS(p.y-q.y));

CGFloat inset = ...;
[_theLayer setNeedsDisplayInRect:CGRectInset(r, inset, inset)];

为了确保只重新渲染实际更改内容所在的图像部分,inset应该是一些(负)插入量,以考虑笔画宽度。

请注意,上面我写的所有内容(除了上下文创建)都会按每个touchesMoved事件调用一次,也就是说,笔画在用户输入它们时(或者,在你的情况下,绘图过程被重播)被渲染和显示,你不需要再渲染或显示它们。


1
我的方法是构建撤销和重做堆栈。以下是代码...它比您要求的多一点,但也许其他人会 a)发现它有用,b)告诉我如何改进它。
视图控制器:
#define kBrushOpacity       (1.0 / 3.0)
#define kBrushPixelStep     3
#define kBrushScale         3
#define kLuminosity         0.75
#define kSaturation         1.0


#define kPaletteHeight          30
#define kPaletteSize            25
#define kMinEraseInterval       0.5

// Padding for margins
#define kLeftMargin             10.0
#define kTopMargin              50.0
#define kRightMargin            10.0
#define kBottomMargin           550.0

#define kCGBlendModePlusLighter 30.0

CGImageRef UIGetScreenImage(void);

@implementation DrawingViewController




- (IBAction)dismiss:(id)sender {
    //NSLog(@"%s", __FUNCTION__);
    [self dismissViewControllerAnimated:YES completion:nil];
}



- (void)viewDidLoad
{
    //NSLog(@"%s", __FUNCTION__);
    [super viewDidLoad];

    pathArray=[[NSMutableArray alloc]init];
    bufferArray=[[NSMutableArray alloc]init];
    tempArray=[[NSMutableArray alloc]init];

    orientation = [[UIApplication sharedApplication] statusBarOrientation];

    [self.window addSubview:window];
    [self.window makeKeyAndVisible];

    drawingView =[[DrawingView alloc]initWithFrame:CGRectMake (0, 0, self.view.bounds.size.width, self.view.bounds.size.height)];
    drawingView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
    [drawingView setBackgroundColor:[UIColor blackColor]];
    //[self backgroundSwitchChange]; 
    [self.view addSubview:drawingView];
    rect = [[UIScreen mainScreen] bounds];  
    brushSize = [[NSUserDefaults standardUserDefaults] valueForKey:@"brushKey"];

    moved = 0;

    [self buildColorBar];
    [self buildToolBar];

    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(brushChange) name:@"brushNotification" object:nil];

    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(pictureChange) name:@"pictureNotification" object:nil];

    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(backgroundSwitchChange) name:@"backgroundNotification" object:nil]; 

    [self showAlert];

    UIGraphicsBeginImageContext(self.view.frame.size);
    [drawImage.image drawInRect:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height)];


    drawImage.image = UIGraphicsGetImageFromCurrentImageContext();
    savedImage.image = drawImage.image;

    UIGraphicsEndImageContext();

}






- (void)viewDidUnload
{
    [super viewDidUnload];
}


- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    //NSLog(@"%s", __FUNCTION__);
    return YES;


}

- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation duration:(NSTimeInterval)duration 
{
    //NSLog(@"%s", __FUNCTION__);

    [toolControls removeFromSuperview];
    [colorControls removeFromSuperview];

    [self buildColorBar];
    [self buildToolBar];

}


- (void)setupNotifications {
    //NSLog(@"%s", __FUNCTION__);

    NSNotificationCenter *dnc = [NSNotificationCenter defaultCenter];      

    [dnc addObserver:self selector:@selector(brushChange) name:@"brushChange:" object:nil]; 
    [dnc addObserver:self selector:@selector(brushColorChange) name:@"createColorNotification" object:nil];

}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
}

#pragma mark - Top Toolbar

-(void) buildToolBar {

    //NSLog(@"%s", __FUNCTION__);


    toolControls = [[UISegmentedControl alloc] initWithItems:
                    [NSArray arrayWithObjects: 
                     [UIImage imageNamed:@"Brush.png"],
                     [UIImage imageNamed:@"Undo.png"],
                     [UIImage imageNamed:@"Redo.png"],
                     [UIImage imageNamed:@"Save.png"],
                     [UIImage imageNamed:@"Erase.png"],
                     [UIImage imageNamed:@"Restore.png"],

                     nil]];

    UIInterfaceOrientation fieldOrient = [[UIApplication sharedApplication] statusBarOrientation];
    if ((fieldOrient == UIDeviceOrientationLandscapeLeft) || (fieldOrient == UIDeviceOrientationLandscapeRight)) {
        //NSLog(@"Landscape");
        CGRect frame = CGRectMake(0, 30, 480, 25 );
        toolControls.frame = frame;

    } else {
        //NSLog(@"Portrait");
        CGRect frame = CGRectMake(0, 30, 320, 25 );
        toolControls.frame = frame;
    }



    [toolControls addTarget:self action:@selector(drawSegmentAction:) forControlEvents:UIControlEventValueChanged];


    toolControls.momentary = YES;    
    toolControls.tintColor = [UIColor grayColor];

    [self.view addSubview:toolControls];

}


- (IBAction)drawSegmentAction:(id)sender
{
    //NSLog(@"%s", __FUNCTION__);

    UISegmentedControl *segmentedControl = (UISegmentedControl *)sender;

    switch (segmentedControl.selectedSegmentIndex){
        case 0: { //Brushes
            [self showBrushes:sender];
            break;
        }
        case 1: { // Undo
            [drawingView undoButtonClicked];
            break;
        }
        case 2: { // Redo           
            [drawingView redoButtonClicked];
            break;
        }

        case 3: { // Save           
            [self saveButtonTapped:self];
            break;
        }

        case 4: { // Erase
            [self eraseButtonTapped:self];
            break;
        }

        case 5: { // Restore
            [self restoreButtonTapped:self];
            break;
        }

        default: {
            //NSLog(@"default");
            break;
        }
    }
}


- (void)doneButtonTapped {    
    [delegate doneButtonTapped];
}


#pragma mark - Color Bar

-(void) buildColorBar {
    //NSLog(@"%s", __FUNCTION__);

    colorControls = [[UISegmentedControl alloc] initWithItems:
                     [NSArray arrayWithObjects: 
                      [UIImage imageNamed:@"White.png"],
                      [UIImage imageNamed:@"Red.png"],


                      nil]];





    UIInterfaceOrientation fieldOrient = [[UIApplication sharedApplication] statusBarOrientation];
    if ((fieldOrient == UIDeviceOrientationLandscapeLeft) || (fieldOrient == UIDeviceOrientationLandscapeRight)) {
        CGRect frame = CGRectMake(0, 230, 480, 25 );
        colorControls.frame = frame;

    } else {

        CGRect frame = CGRectMake(0, 390, 320, 25 );
        colorControls.frame = frame;
    }

    // Add LongTap Color options

    gesture = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(showMoreColors:)];
    gesture.minimumPressDuration = 1.0;    
    [colorControls addGestureRecognizer:gesture];

    //gesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(showMoreColors:)];
    //[gesture setNumberOfTapsRequired:2];  
    //[colorControls addGestureRecognizer:gesture];

    // When the user chooses a color, the method changeColor: is called.
    [colorControls addTarget:self action:@selector(changeColor:) forControlEvents:UIControlEventValueChanged];

    colorControls.segmentedControlStyle = UISegmentedControlStyleBar;

    // Make sure the color of the color complements the black background
    colorControls.tintColor = [UIColor grayColor];

    // Add the control to the window
    [self.view addSubview:colorControls];


}

// Change the brush color

- (IBAction)changeColor:(id)sender {
    //NSLog(@"%s", __FUNCTION__);

    colorIndex = [sender selectedSegmentIndex];
    AppDelegate *mainDelegate = (AppDelegate *) [[UIApplication sharedApplication] delegate];
    mainDelegate.colorIndex  = colorIndex;

    switch (colorIndex) {
        case 0:
            colorKey = @"0";
            break;

        case 1:
            colorKey = @"1";
            break;

        case 2:
            colorKey = @"2";
            break;

        case 3:
            colorKey = @"3";
            break;



        default:
            break;

    }

    [[NSUserDefaults standardUserDefaults] setObject: colorKey forKey: @"colorKey"];
    [[NSNotificationCenter defaultCenter] postNotificationName: @"ColorChange" object: nil];
    [drawingView changeColor:sender];
}

-(void) showMoreColors:(id)sender {
    //NSLog(@"%s", __FUNCTION__);

    switch (colorIndex) {
        case 0:
            [self showMoreWhiteColors:(id)sender];
            break;

        case 1:
            [self showMoreRedColors:(id)sender];
            break;

        case 2:
            [self showMoreYellowColors:(id)sender];
            break;

        case 3:
            [self showMoreGreenColors:(id)sender];
            break;

        case 4:
            [self showMoreBlueColors:(id)sender];
            break;

        case 5:
            [self showMorePurpleColors:(id)sender];
            break;

        case 6:
            [self showMoreBlackColors:(id)sender];
            break;

        default:
            break;

    }
}



#pragma mark - Brushes 

//delegate methods
- (void)brushesViewControllerDidFinish:(BrushesViewController *)controller
{
    //NSLog(@"%s", __FUNCTION__);
    [self brushChange];

}

- (void)brushChange { //from notification
    //NSLog(@"%s", __FUNCTION__);
    brushSize = [[NSUserDefaults standardUserDefaults] objectForKey:@"brushKey"];
    [drawingPath brushChange];
}

- (IBAction)showBrushes:(id)sender
{
    //NSLog(@"%s", __FUNCTION__);

    BrushesViewController *controller = [[BrushesViewController alloc] initWithNibName:@"Brushes" bundle:nil];
    controller.delegate = self;
    [self presentViewController:controller animated:YES completion:nil];
}

- (void)changeBrushSize:(id)sender {
    //NSLog(@"%s", __FUNCTION__);

}



#pragma mark - Colors


- (void)whiteViewControllerDidFinish:(WhiteViewController *)controller
{
    //NSLog(@"%s", __FUNCTION__);
    [[NSNotificationCenter defaultCenter] postNotificationName: @"ColorChange" object: nil];
    [drawingView changeColor:self]; 
}

- (void)redViewControllerDidFinish:(RedViewController *)controller
{
    //NSLog(@"%s", __FUNCTION__);
    [[NSNotificationCenter defaultCenter] postNotificationName: @"ColorChange" object: nil];
    [drawingView changeColor:self]; 
}

- (void)greenViewControllerDidFinish:(GreenViewController *)controller
{
    //NSLog(@"%s", __FUNCTION__);
    [[NSNotificationCenter defaultCenter] postNotificationName: @"ColorChange" object: nil];
    [drawingView changeColor:self];

}




- (void)purpleViewControllerDidFinish:(PurpleViewController *)controller
{
    //NSLog(@"%s", __FUNCTION__);
    [[NSNotificationCenter defaultCenter] postNotificationName: @"ColorChange" object: nil];
    [drawingView changeColor:self];

}



- (IBAction)showMoreWhiteColors:(id)sender {
    //NSLog(@"%s", __FUNCTION__);

        WhiteViewController *controller = [[WhiteViewController alloc] initWithNibName:@"White" bundle:nil];
        controller.delegate = self;
        [self presentViewController:controller animated:YES completion:nil];

}


- (IBAction)showMoreRedColors:(id)sender
{
    //NSLog(@"%s", __FUNCTION__);

        RedViewController *controller = [[RedViewController alloc] initWithNibName:@"Red" bundle:nil];
        controller.delegate = self;
        [self presentViewController:controller animated:YES completion:nil];   

}


- (IBAction)showMoreYellowColors:(id)sender {
    //NSLog(@"%s", __FUNCTION__);

        YellowViewController *controller = [[YellowViewController alloc] initWithNibName:@"Yellow" bundle:nil];
        controller.delegate = self;
        [self presentViewController:controller animated:YES completion:nil];


}


- (IBAction)showMoreBlackColors:(id)sender {


        BlackViewController *controller = [[BlackViewController alloc] initWithNibName:@"Black" bundle:nil];
        controller.delegate = self;
        [self presentViewController:controller animated:YES completion:nil];


}



#pragma mark - Save

- (IBAction)saveButtonTapped:(id)sender
{


    [self captureToPhotoAlbum];
    [self flashScreen];

}



-(void)captureToPhotoAlbum {
         //NSLog(@"%s", __FUNCTION__);      

         UIScreen *screen = [UIScreen mainScreen];
         CGRect screenRect = screen.bounds; //implicitly in Portrait orientation.        

    UIInterfaceOrientation fieldOrient = [[UIApplication sharedApplication] statusBarOrientation];
    if ((fieldOrient == UIDeviceOrientationLandscapeLeft) || (fieldOrient == UIDeviceOrientationLandscapeRight)) {
         CGRect temp;
         temp.size.width = screenRect.size.height;
         temp.size.height = screenRect.size.width;
         screenRect = temp;      
         }


         UIGraphicsBeginImageContext(screenRect.size);
         CGContextRef ctx = UIGraphicsGetCurrentContext(); 
         [[UIColor blackColor] set]; 
         CGContextFillRect(ctx, screenRect);
         [self.view.layer renderInContext:ctx];
         UIImage *img = UIGraphicsGetImageFromCurrentImageContext();
         UIGraphicsEndImageContext();


         if ([[UIScreen mainScreen] respondsToSelector:@selector(scale)] && [[UIScreen mainScreen] scale] == 2.0) {
         // Retina
         // Image cropping This is the size of the saved image.
         //NSLog(@"height is %f", self.view.bounds.size.height );
         CGImageRef imageRef = CGImageCreateWithImageInRect
         ([img CGImage], 
         CGRectMake (0, 75, (self.view.bounds.size.width * 2), (self.view.bounds.size.height -130)));
         // NSLog(@"width is %f", self.view.bounds.size.width * 2 );
         UIImage *img2Save = [UIImage imageWithCGImage:imageRef];
         CGImageRelease(imageRef);
         // Request to save the image to camera roll
         UIImageWriteToSavedPhotosAlbum(img2Save, self, nil, nil);

         } else {

         CGImageRef imageRef = CGImageCreateWithImageInRect
         ([img CGImage], 
         CGRectMake (0, 75, self.view.bounds.size.width, (self.view.bounds.size.height - 130)));

         UIImage *img2Save = [UIImage imageWithCGImage:imageRef];
         CGImageRelease(imageRef);
         // Request to save the image to camera roll
         UIImageWriteToSavedPhotosAlbum(img2Save, self, nil, nil); 
         }

    }



-(void) flashScreen {
    //NSLog(@"%s", __FUNCTION__);
    UIWindow* wnd = [UIApplication sharedApplication].keyWindow;
    UIView* v = [[UIView alloc] initWithFrame: CGRectMake(0, 0, wnd.frame.size.width, wnd.frame.size.height)];
    [wnd addSubview: v];
    v.backgroundColor = [UIColor whiteColor];
    [UIView beginAnimations: nil context: nil];
    [UIView setAnimationDuration: 1.0];
    v.alpha = 0.0f;
    [UIView commitAnimations];
}




#pragma mark - Undo Redo


-(IBAction)undoButtonTapped:(id)sender
{
    //NSLog(@"%s", __FUNCTION__);

    [drawingView undoButtonClicked];
}

-(IBAction)redoButtonTapped:(id)sender
{
    //NSLog(@"%s", __FUNCTION__);

    [drawingView redoButtonClicked];


}


#pragma mark - Erase / Restore

- (IBAction)eraseButtonTapped:(id)sender {
    //NSLog(@"%s", __FUNCTION__);
    savedImage.image = drawImage.image;
    [drawingView eraseButtonClicked];
    undoFlag = 1;
}


- (IBAction)restoreButtonTapped:(id)sender {
    //NSLog(@"%s", __FUNCTION__);   

    if (undoFlag == 1) {
        drawImage.image = savedImage.image;
        [drawingView restoreButtonClicked];
        undoFlag = 0;
    }

}

@end

UIView:

#import "DrawingView.h"

float red = 0;
float green = 1;
float blue = 0;
float alpha = 50;

- (id)initWithFrame:(CGRect)frame
{
    //NSLog(@"%s", __FUNCTION__);
    if (!(self = [super initWithFrame:frame]))
        return nil;

    [self initializeView];    
    return self;

}

- (id)initWithCoder:(NSCoder *)aDecoder {
    //NSLog(@"%s", __FUNCTION__);
    if (!(self = [super initWithCoder:aDecoder])) 
        return nil;

    [self initializeView];    
    return self;
}

- (void)initializeView {
    _currentColor = [UIColor greenColor];
    _currentArray = [NSMutableArray array];
    _bufferArray = [NSMutableArray array];
    _redoStack = [NSMutableArray array];
    _result = @"NO";
    myPath=[[UIBezierPath alloc]init];
    myPath.lineCapStyle=kCGLineCapRound;

    [self setUserInteractionEnabled:YES];
}


- (void)drawRect:(CGRect)rect {
    //NSLog(@"%s", __FUNCTION__);
    for (DrawingPath *drawingPath in self.currentArray) {
        [drawingPath draw];
    }
}

#pragma mark - Actions

- (void)eraseButtonClicked {
    //NSLog(@"%s", __FUNCTION__);
    self.bufferArray = [self.currentArray mutableCopy];

    [self.currentArray removeAllObjects];
    [self setNeedsDisplay];

}

- (void)restoreButtonClicked {
    //NSLog(@"%s", __FUNCTION__);   
    self.currentArray = [self.bufferArray mutableCopy];
    [self.bufferArray removeAllObjects];
    [self setNeedsDisplay]; 
}

-(void)undoButtonClicked
{
    //NSLog(@"%s", __FUNCTION__);
    if ([self.currentArray count] == 0) {
        //nothing to undo
        return;
    }

    DrawingPath *undonePath = [self.currentArray lastObject];
    [self.currentArray removeLastObject];
    [self.redoStack addObject:undonePath];
    [self setNeedsDisplay];

}

-(void)redoButtonClicked
{
    //NSLog(@"%s", __FUNCTION__);

    if ([self.redoStack count] == 0) {
        // nothing to redo
        return;
    }

    DrawingPath *redonePath = [self.redoStack lastObject];
    [self.redoStack removeLastObject];
    [self.currentArray addObject:redonePath];
    [self setNeedsDisplay];

}


#pragma mark - Touch Methods
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{   
    //NSLog(@"%s", __FUNCTION__);
    self.currentColoredPath = [[DrawingPath alloc] init];
    [self.currentColoredPath setColor:self.currentColor];
    UITouch *touch= [touches anyObject];


    [self.currentColoredPath.path moveToPoint:[touch locationInView:self]];
    [self.currentArray addObject:self.currentColoredPath];
    // Remove all paths from redo stack
    [self.redoStack removeAllObjects];

    lastPoint = [touch locationInView:self];
    lastPoint.y -= 20;

    if ([touch tapCount] == 2) {
        [self alertOKCancelAction];

        return;
    }  


}



-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
    //NSLog(@"%s", __FUNCTION__);
    UITouch *touch = [touches anyObject]; 
    [self.currentColoredPath.path addLineToPoint:[touch locationInView:self]];

    [self setNeedsDisplay];


    CGPoint currentPoint = [touch locationInView:self];
    currentPoint.y -= 20;


    lastPoint = currentPoint;

}

-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
    //NSLog(@"%s", __FUNCTION__);
    self.currentColoredPath = nil;
}



# pragma mark - Brush Colors

// Change the brush color
- (void)changeColor:(id)sender

{

    //NSLog(@"%s", __FUNCTION__);
    colorKey = [[NSUserDefaults standardUserDefaults] objectForKey:@"colorKey"];
    colorIndex = [colorKey intValue];



    switch (colorIndex) {
        case 0:         
            red = 1;
            green = 1;
            blue = 1;           
            //[selectSound play];
            break;

        case 1:         
            red = 1;
            green = 0;
            blue = 0;           
            //[selectSound play];
            break;

        case 2:         
            red = 1;
            green = 1;
            blue = 0;           
            //[selectSound play];
            break;

        case 3:         
            red = 0;
            green = 1;
            blue = 0;
            //[selectSound play];
            break;

        case 4:         
            red = 0.11764f;
            green = 0.56470f;
            blue = 1;
            //[selectSound play];
            break;

        case 5:         
            red = 1;
            green = 0.41176f;
            blue = 0.70588f;
            //[selectSound play];
            break;

        case 6:             
            red = 0;
            green = 0;
            blue = 0;
            //[selectSound play];
            break;

            //WHITE 

        case 11:            
            red = 0.949020f;
            green = 0.949020f;
            blue = 0.949020f;           
            //[selectSound play];
            break;

        case 12:            


        case 13:            



        default: 
            break;
    }
    //NSLog(@"ColorIndex is %i", colorIndex);

    self.currentColor = [UIColor colorWithRed:red green:green blue:blue alpha:1];

}

#pragma mark - Alerts

- (void)shakeOKCancelAction {
    // open a alert with an OK and cancel button
    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"SHAKE", nil) message: NSLocalizedString(@"SHAKEERASE", nil) delegate:self cancelButtonTitle:@"NO" otherButtonTitles:@"YES", nil];
    [alert show];
}


- (void)alertOKCancelAction {
    // open a alert with an OK and cancel button
    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"TWICE", nil) message: NSLocalizedString(@"TAPERASE", nil) delegate:self cancelButtonTitle:@"NO" otherButtonTitles:@"YES", nil];
    [alert show];
}


- (void)alertView:(UIAlertView *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex {
    // the user clicked one of the Alert buttons
    if (buttonIndex == 0)
    {
        return;
    }
    else
    {
        [self eraseButtonClicked];
        return;
    }
}


@end

and object:


@implementation DrawingPath

@synthesize path = _path;
@synthesize color = _color;
@synthesize brushSize = _brushSize;
float brush = 12;

- (id)init {

    if (!(self = [super init] ))
        return nil;
    brushSize = [[NSUserDefaults standardUserDefaults] objectForKey:@"brushKey"];
    [self brushChange];


    _path = [[UIBezierPath alloc] init];
    _path.lineCapStyle=kCGLineCapRound;
    _path.lineJoinStyle=kCGLineJoinRound;

    [_path setLineWidth:brush];



  //  _color = [UIColor blackColor];

    return self;
}

- (void)draw {

    [self.color setStroke];
    [self.path stroke];
}

- (void)brushChange { //from notification


    brushSize = [[NSUserDefaults standardUserDefaults] objectForKey:@"brushKey"];
    //NSLog(@"DrawingPath - brushSize is %@: ", brushSize );

    if (brushSize == @"128")  brush = 128;
    if (brushSize == @"64")  brush = 64;
    etc


}



@end

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接