Domanda

I'm attempting to create a 'patterned brush stroke' effect in my app. I'm achieving this using CGContextStrokePath with a patterned UIColor. This is giving me the below problem.

When I draw a straight line, it works fantastically, e.g:

enter image description here

Yet when I draw a diagonal stroke, I get this:

enter image description here

Whereas I'm actually aiming for this:

enter image description here

(The difference in orientation of the pattern is the issue here, not my shoddy image cropping!)

What I've been trying to do thus far, is look for a way to control the orientation in which the pattern is tiled/displayed, yet I haven't managed to figure out a method to do this. Can anyone enlighten me, or tell me how I should be doing it instead?

Current code included for completeness below.

- (void)drawRect:(CGRect)rect
{
    [super drawRect:rect];

    // get the current context
    CGContextRef context = UIGraphicsGetCurrentContext();

    //Create a pattern
    NSString* theFilePath = [[NSBundle mainBundle] pathForResource: @"iceliteTrial.png" ofType: nil];
    UIImage* theGrassPatternImage = [UIImage imageWithContentsOfFile: theFilePath];
    UIColor* iceLitePattern = [UIColor colorWithPatternImage: theGrassPatternImage];
    CGSize phase = CGSizeMake(self.lineStart.x, self.lineStart.y-30);
    CGContextSetPatternPhase(context,phase);

    // set the stroke color and width
    CGContextSetStrokeColorWithColor(context, iceLitePattern.CGColor);
    CGContextSetLineWidth(context, 60.0);

    // move to your first point
    CGContextMoveToPoint(context, self.lineStart.x, self.lineStart.y);

   // add a line to your second point
    CGContextAddLineToPoint(context, self.lineEnd.x, self.lineEnd.y);

    // tell the context to draw the stroked line
    CGContextStrokePath(context);

}
È stato utile?

Soluzione

Rather than using CGContext I would recommend switching to using a CAShapeLayer. I used this approach in one of my apps like this:

//call this on every drawRect: call.
-(void)makeLineLayer:(CALayer *)layer{
    CAShapeLayer *line = [CAShapeLayer layer];
    UIBezierPath *linePath=[UIBezierPath bezierPath];
    [linePath moveToPoint:self.lineStart];
    [linePath addLineToPoint:self.lineEnd];
    [linePath setLineWidth:60.0];

    line.path=linePath.CGPath;
    line.fillColor = nil;
    line.opacity = 1.0;
    [layer addSublayer:line];
}

This will give you the line between the two points. From Here I would recommend adding a CALayer to the CAShapeLayer and set its contents property to your image. Here is a link to an article describing how to tile an image in a CALayer. Then you wold need to calculate the angle of the CAShapeLayer and rotate the CALayer by that angle.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top