使用UIBezierPath平滑的画线

该博客介绍如何利用UIBezierPath在UIView上实现平滑的画线操作。通过创建UIBezierPath对象,设置线条颜色和宽度,结合触摸事件追踪用户轨迹,实现了绘制和擦除功能。此外,还提供了撤销、重置颜色和线条宽度的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

UIBezierPath 是根据 Core Graphic Framework 写出的 Class ,能够让我们在 UIView 上画出我们需要的图形,主要就是一个UIBezierPath对象和一个UIColor对象保存画笔的颜色。

@implementation SmoothDrawDoodleView

@synthesize parentView;

@synthesize lastImage;

@synthesize path;

//@synthesize incrementalImage;

@synthesize drawingColor;

@synthesize pathArray;

@synthesize colorArray;

- (id)initWithFrame:(CGRect)frame

{

    self = [super initWithFrame:frame];

    penAlpha=1.0f;

    piontSize = 6.0;

    if (self) {

        self.backgroundColor = [UIColor clearColor];

        [self setMultipleTouchEnabled:NO];

        self.path = [UIBezierPath bezierPath];

        self.drawingColor = [UIColor blackColor];

        [self.path  setLineWidth:piontSize];

        self.pathArray =[NSMutableArray arrayWithObject:self.path];

        self.colorArray =[NSMutableArray arrayWithObject:self.drawingColor];

    }

    return self;

}


// Only override drawRect: if you perform custom drawing.

// An empty implementation adversely affects performance during animation.

- (void)drawRect:(CGRect)rect

{

    //before paint,pait all before line

    if(isErase  == NO)

    {

        for (int i=0; i<[pathArray count]; i++) {

    //        [self.drawingColor setStroke];

    //        //[self.incrementalImage drawInRect:rect];

    //        [self.path stroke];

            UIBezierPath* bezierPath=(UIBezierPath*)[pathArray objectAtIndex:i];

            UIColor* color=(UIColor*)[colorArray objectAtIndex:i];

            [color setStroke];

            [bezierPath strokeWithBlendMode:kCGBlendModeNormal alpha:1.0f];

        }

    }else

    {

        UIGraphicsBeginImageContext(self.bounds.size);

        CGContextRef context = UIGraphicsGetCurrentContext();

        CGContextClearRect(context, CGRectMake(rect.origin.x , rect.origin.y, 20, 20));

        UIGraphicsEndImageContext();

        

    }

}



- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event

{

    [parentView setSegmentDefaultValue];

    if (self.lastImage) {

        [[parentView.undoManager prepareWithInvocationTarget:parentView] setDoodleImage:[parentView mergeImage:parentView.drawImage.image overImage:self.lastImage]];

    }else {

        [[parentView.undoManager prepareWithInvocationTarget:parentView] setDoodleImage:parentView.drawImage.image];

    }

    ctr = 0;

    UITouch *touch = [touches anyObject];

    pts[0] = [touch locationInView:self];

}


- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event

{

    UITouch *touch = [touches anyObject];

    CGPoint p = [touch locationInView:self];

    if(isErase == YES)

    {

//        UIGraphicsBeginImageContext(self.bounds.size);

//        CGContextClearRect(UIGraphicsGetCurrentContext(), CGRectMake(p.x , p.y, 20, 20));

//        UIGraphicsEndImageContext();

        [self setNeedsDisplay];

    }else{

        ctr++;

        pts[ctr] = p;

        if (ctr == 4)

        {

            pts[3] = CGPointMake((pts[2].x + pts[4].x)/2.0, (pts[2].y + pts[4].y)/2.0); // move the endpoint to the middle of the line joining the second control point of the first Bezier segment and the first control point of the second Bezier segment

            

            [path moveToPoint:pts[0]];

            [path addCurveToPoint:pts[3] controlPoint1:pts[1] controlPoint2:pts[2]];

            

            [self setNeedsDisplay];

            // replace points and get ready to handle the next segment

            pts[0] = pts[3];

            pts[1] = pts[4];

            ctr = 1;

        }

    }

}


- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event

{

    [self setNeedsDisplay];

    ctr = 0;

}


- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event

{

    [self touchesEnded:touches withEvent:event];

}

//save the view change into image

- (UIImage *)imageRepresentation {

   UIGraphicsBeginImageContext(self.bounds.size);

    [self.layer renderInContext:UIGraphicsGetCurrentContext()];

    self.lastImage = UIGraphicsGetImageFromCurrentImageContext();

    UIGraphicsEndImageContext();

    return self.lastImage;

}

//erase the line

- (void)erase

{

//    self.path = [UIBezierPath bezierPath];

//    self.path.lineWidth =piontSize;

//    self.drawingColor=[UIColor whiteColor];

//    [pathArray addObject:self.path];

//    [colorArray addObject:self.drawingColor];

//    [self setNeedsDisplay];

    isErase = YES;

}

//clear the paint

-(void)clear

{

    [pathArray removeAllObjects];

    [colorArray removeAllObjects];

    [self setNeedsDisplay];

    self.path = [UIBezierPath bezierPath];

    self.path.lineWidth =piontSize;

    [pathArray addObject:self.path];

    [colorArray addObject:self.drawingColor];

}

//undo the paint

-(void)undo

{

    //remove the last paint line

    [pathArray removeLastObject];

    [colorArray removeLastObject];

    [self setNeedsDisplay];

    if ([pathArray count] == 0) {

        self.path = [UIBezierPath bezierPath];

        self.path.lineWidth =piontSize;

        [pathArray addObject:self.path];

        [colorArray addObject:self.drawingColor];

    }else//use the last bezierpath to paint

    {

        self.path=(UIBezierPath*)[pathArray lastObject];

        self.drawingColor=(UIColor*)[colorArray lastObject];

    }

}

- (void)setBrushColor:(CGFloat)red green:(CGFloat)green blue:(CGFloat)blue

{

    redColor = red;

    greenColor = green;

    blueColor = blue;

    self.path = [UIBezierPath bezierPath];

    self.path.lineWidth =piontSize;

    self.drawingColor=[UIColor colorWithRed:red green:green blue:blue alpha:penAlpha];

    [pathArray addObject:self.path];

    [colorArray addObject:self.drawingColor];

}

- (void)setLinePiontSize:(float)pointSize

{

    self.path = [UIBezierPath bezierPath];

    piontSize=pointSize;

    path.lineWidth = piontSize;

    [pathArray addObject:self.path];

    [colorArray addObject:self.drawingColor];

}

-(void)setPenAlpha:(float)penAlpha_

{

    penAlpha = penAlpha_;

    [self setBrushColor:redColor green:greenColor blue:blueColor];

}

-(void)dealloc

{

    [path release];

    [drawingColor release];

    [parentView release];

    [lastImage release];

    [pathArray release];

    [colorArray release];

    [super dealloc];

}

@end


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值