Julian F. Weinert
Julian F. Weinert

Reputation: 7560

UIBezierPath draw line representation

I wrote a simple drawing code using UIBezierPath and the -touches... methods of UIView. The drawing works great, but I made some bad experiences.

  1. When I'm painting very slow, it works great. But the more fast I draw, the more edgy the line gets. So how do I like "smooth" them to become less edgy (more points)?

  2. When I use setLineWidth with high line widths, the line become very ugly.

Here is an image to show what ugly actually means: This actually means "ugly"

Why does it draw fat line in that way?!

EDIT: here some code

- (void)drawInRect:(CGRect)rect
{
    for(UIBezierPath *path in pathArray) {
        [[UIColor blackColor] setStroke];
        [path setLineWidth:50.0];
        [path stroke];
    }
}
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    startPoint = [[touches anyObject] locationInView:self];
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
    UIBezierPath *path = [UIBezierPath bezierPath];
    [path moveToPoint:startPoint];
    [path addLineToPoint:[[touches anyObject] locationInView:self]];
    if(isDrawing) {
        [pathArray removeLastObject];
    }
    else {
        isDrawing = YES;
    }
    [pathArray addObject:path];
    [path close];
    [self setNeedsDisplay];
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
    isDrawing = NO;
}

I hope that somebody can help me with these issues. THANKS a lot, greets, Julian

Upvotes: 1

Views: 1950

Answers (1)

mprivat
mprivat

Reputation: 21902

Mmmmh, I'm not going to address performance issues with your implementation in this thread, but take a look at setNeedsDisplayInRect: in UIView once you get the basics working.

I think you're basically trying to take out the last created path from your array and replace it with a new one for as long as you're moving.

You should try to put a CGMutablePathRef in your array instead (take a look here for that CGMutablePathRef to NSMutableArray).

The basic flow would be something like:

  1. touchesBegan:

    1. Create the CGMutablePathRef
    2. Call moveToPoint
    3. Store in the array
  2. touchesMoved:

    1. Get the lastObject from your array (i.e. the CGMutablePathRef)
    2. Call addLineToPoint
    3. [self setNeedsDisplay]

Then in drawInRect, iterate through your paths and paint them.

Again, this will be slow at first, then you need to optimize. CGLayerRef can help. setNeedsDisplayInRect most definitely will also.

Upvotes: 1

Related Questions