15

I draw a shape by UIBezierPath in touchesMoved.

-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
    UITouch *touch = [touches anyObject];
    secondPoint = firstPoint;
    firstPoint = [touch previousLocationInView:self];
    currentPoint = [touch locationInView:self];

    CGPoint mid1 = midPoint(firstPoint, secondPoint);
    CGPoint mid2 = midPoint(currentPoint, firstPoint);

    [bezierPath moveToPoint:mid1]; 
    [bezierPath addQuadCurveToPoint:mid2 controlPoint:firstPoint];

    [self setNeedsDisplay]; 
}

I want to fill RED color inside it after closePath but can't. Please help!

- (void)drawRect:(CGRect)rect
{
    UIColor *fillColor = [UIColor redColor];
    [fillColor setFill];
    UIColor *strokeColor = [UIColor blueColor];
    [strokeColor setStroke];
    [bezierPath closePath];
    [bezierPath fill];
    [bezierPath stroke]; 
}
LE SANG
  • 10,955
  • 7
  • 59
  • 78
  • It doesn't look like you are actually stroking a path, so there isn't one to close. – Abizern Mar 12 '13 at 10:33
  • 1
    Could you give an answer.I don't understand so much. Thanks! – LE SANG Mar 12 '13 at 10:35
  • Let me guess? you aren't getting a shape, just a line? Every time your touch moves it closes the current subpath. – Abizern Mar 12 '13 at 10:45
  • Yes, Sir! only blue line.I understand closePath make a shape? Very bad. – LE SANG Mar 12 '13 at 10:45
  • Your code is fine except that `setFill` doesn't actually set the fill context as you'd expect (see this: https://stackoverflow.com/questions/10623545/uicolor-setfill-doesnt-work/10623961). Instead, set the fill with the obj-C equivalent of `let context = UIGraphicsGetCurrentContext()!; context.setFillColor(UIColor.blue.cgColor)` – pseudosudo Nov 13 '18 at 18:07

2 Answers2

19

If you have a bezier path stored elsewhere, this should work:

Edit

Looking at your edited code, what is happening is that as you are closing the path that you are drawing is getting closed - so you get a line, not a shape since you have only two points.

One way around this is to create the path as your points move, but stroke and fill a copy of that path. For example this is untested code, I'm writing it straight in

-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
    UITouch *touch = [touches anyObject];
    secondPoint = firstPoint;
    firstPoint = [touch previousLocationInView:self];
    currentPoint = [touch locationInView:self];

    CGPoint mid1 = midPoint(firstPoint, secondPoint);
    CGPoint mid2 = midPoint(currentPoint, firstPoint);

    [bezierPath moveToPoint:mid1]; 
    [bezierPath addQuadCurveToPoint:mid2 controlPoint:firstPoint];

    // pathToDraw is an UIBezierPath * declared in your class
    pathToDraw = [[UIBezierPath bezierPathWithCGPath:bezierPath.CGPath];

    [self setNeedsDisplay]; 
}

And then your drawing code can:

- (void)drawRect:(CGRect)rect {
    UIColor *fillColor = [UIColor redColor];
    [fillColor setFill];
    UIColor *strokeColor = [UIColor blueColor];
    [strokeColor setStroke];

    // This closes the copy of your drawing path.
    [pathToDraw closePath];

    // Stroke the path after filling it so that you can see the outline
    [pathToDraw fill]; // this will fill a closed path
    [pathToDraw stroke]; // this will stroke the outline of the path.

}

There is some tidying up to do an touchesEnded and this could be made more performant, but you get the idea.

Abizern
  • 146,289
  • 39
  • 203
  • 257
  • How to fill color for a closed bezirepath on CAShapelayer.For me it is always black in color. – Madhu Jan 23 '15 at 13:18
-4

You have to keep array of your UIBezierPaths. Try this code,

 - (void)drawRect:(CGRect)rect
    {

        for(UIBezierPath *_path in pathArray){


         [_path fill];
        [_path stroke];
        }
    }

    #pragma mark - Touch Methods
    -(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
    {
        myPath=[[UIBezierPath alloc]init];
        myPath.lineWidth = currentSliderValue;

        UITouch *mytouch=[[touches allObjects] objectAtIndex:0];
        [myPath moveToPoint:[mytouch locationInView:self]];
        [pathArray addObject:myPath];
    }
    -(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
    {
        UITouch *mytouch=[[touches allObjects] objectAtIndex:0];
        [myPath addLineToPoint:[mytouch locationInView:self]];
        [self setNeedsDisplay];

    }
Hasintha Janka
  • 1,608
  • 1
  • 14
  • 27