Why is the CG Path always fading out? - ios

I have a weird issue with some basic drawing code here:
The code for this is just the following in a for-loop, I just want to draw some vertical lines into the view:
UIBezierPath* verticalLine = [UIBezierPath bezierPath];
[verticalLine moveToPoint:CGPointMake(currentXPosition, 0)];
[verticalLine addLineToPoint:CGPointMake(currentXPosition, self.frame.size.height)];
[verticalLine closePath];
verticalLine.lineWidth = 1;
[[UIColor blackColor] setStroke];
[verticalLine stroke];
I can't imagine a reason for it. Can you?
Thanks in advance,
Christian
EDIT: Drawing horizontal lines works perfectly well, they have normal width and don't fade out.

Related

CAShapeLayer draws a circle in center as a sideeffect of line cap set to kCALineJoinRound

I'm drawing a segment of a pie chart with the following code:
CAShapeLayer *segment = [CAShapeLayer layer];
UIBezierPath *segmentPath = [UIBezierPath bezierPath];
[segmentPath addArcWithCenter:segmentCenter radius:segmentRadius startAngle:angle1 endAngle:angle2 clockwise:YES];
segment.path = [segmentPath CGPath];
[segment setLineCap:kCALineJoinRound]; // this is the line which causes this
segment.lineWidth = 8;
segment.fillColor = [[UIColor clearColor] CGColor];
segment.strokeColor = [[UIColor orangeColor] CGColor];
[self.layer addSublayer:segment];
and as a sideffect of setting kCALineJoinRound I get also a little circle inside. I need to get rid of it, can you help me?
Solved, the problem was due to the CAShapeLayer being added twice in layoutSubviews which caused this strange effect.

Tableview seperator appears as a triangle

Is there a way to get a tableview seperator effect like the screenshot below, the effect has been used in the fast company app and shows two rows in the views being separated by a triangular seperator.
Any pointers on how this effect can be achieved in a tableview would be highly appreciated. The seperator at the bottom of the screen is semi transparent and the image associated with the next row shows through.
A link to the screenshot is here: https://s3-us-west-1.amazonaws.com/jjm.so/17427B2C-3837-4428-B82E-8D1C57BFA706B53CD936-AE93-4F2A-B3DB-7F7018A02CBA.jpg
There you go:
CGRect frame = imageView.bounds;
UIBezierPath *path = [UIBezierPath bezierPath];
[path moveToPoint:CGPointMake(0, frame.size.height)];
[path addLineToPoint:CGPointMake(0, frame.size.height-60)];
[path addLineToPoint:CGPointMake(frame.size.width/2, frame.size.height-20)];
[path addLineToPoint:CGPointMake(frame.size.width, frame.size.height-60)];
[path addLineToPoint:CGPointMake(frame.size.width, frame.size.height)];
[path closePath];
CAShapeLayer *mask = [CAShapeLayer layer];
mask.path = path.CGPath;
mask.strokeColor = [UIColor clearColor].CGColor;
mask.fillColor = [UIColor colorWithRed:0.1 green:0.1 blue:0.1 alpha:0.5].CGColor;
[imageView.layer addSublayer:mask];
I think you use ImageMasking on that, It may be Help you. Just simple create Image of Layer which is you required.and then Just add masking too Image.
I think that is a custom UIView inside the cell that is created by drawing a bezierPathto get the shape. The UIView is having a colour of 0,0,0 and alpha of 0.3-0.4 and is a subview of the cell.contentView. The tableview has separator as None,and the custom view lies at the bottom of the cell, thus rendering the effect that it is being used as a custom separator of triangle shape.

Draw multiple lines Core Graphics

I have a custom view that will draw animations - just different lines, each line a different color. When user enters information, these lines appear originating at the button and creating lines to different UILabels.
I am following this tutorial techotopia.com core graphics iOS 7 tutorial
It says to make the UIView a custom class and put the drawing inside drawRect: - with your typical creating of context, adding lines, stroke, color, etc. OK fine, but how do I get multiple lines with different colors to be drawn simultaneously?
Do I need to create layers for each line? A new custom class and view for each line?
If I call CGPathCloseSubpathwill that allow me to create a new starting point?
How do I change the color for the new line, and do I need to create a new context for the new line?
Use UIBezierPath is easier than CGPath and CGContext.
-(void)drawRect:(CGRect)rect
{
UIBezierPath *line1 = [UIBezierPath bezierPath];
[line1 moveToPoint:CGPointMake(0, 0)];
[line1 addLineToPoint:CGPointMake(100, 0)];
[[UIColor redColor] set]; //Set color to red
[line1 stroke];
UIBezierPath *line2 = [UIBezierPath bezierPath];
[line2 moveToPoint:CGPointMake(0, 10)];
[line2 addLineToPoint:CGPointMake(100, 10)];
[[UIColor blueColor] set]; //Change color to blue
[line2 stroke];
}

How to fill a CGPathRef overlap like this?

I want to draw a single path, which can overlap itself. What I want is like a snap of Moves below:
Can I achieve this just fill a single CGPathRef on iOS?
I created two paths, a gray one and red one below:
There are two overlaps on the gray line, one for itself and one for the red line. The red overlap, you can see it clearly, is above (or below) the gray one. But the gray overlap is just merged.
The Moves trace line is a single line, maybe is not implemented by a single path fill or stroke.
Here's my code:
[[UIColor colorWithWhite:0.0 alpha:0.3] setStroke];
CGFloat lineWidth = 10.0;
UIBezierPath *path = [UIBezierPath bezierPath];
path.lineWidth = lineWidth;
[path moveToPoint:CGPointMake(300, 50)];
[path addLineToPoint:CGPointMake(20, 400)];
[path addLineToPoint:CGPointMake(300, 400)];
[path addLineToPoint:CGPointMake(20, 50)];
[path stroke];
[[UIColor colorWithRed:1.0 green:0.5 blue:0.5 alpha:0.5] setStroke];
UIBezierPath *anotherPath = [UIBezierPath bezierPath];
anotherPath.lineWidth = lineWidth;
[anotherPath moveToPoint:CGPointMake(160, 50)];
[anotherPath addLineToPoint:CGPointMake(300, 200)];
[anotherPath stroke];

Drawing overlapping shapes in drawRect with different color causes edge-bleeding when anti-aliassing is enabled

I have a problem when drawing to equal shapes with a different color that overlap. When enabling anti-aliassing the transparent pixels that get generated bleed through and causes the artifacts as in this image. The sequence her is drawing a red circle, drawing a blue triangle and then drawing a red triangle.
This problem is solvable by disabling anti-aliassing but the outcome are ugly jagged edges.
Are there for instance solutions where I can retro-actively anti-alias the graphic context or render to an image and anti-alias on that image. Or anything else that can help me draw overlapping shapes with crisp edges.
Here is the code to recreate the problem
-(void)drawRect:(CGRect)rect
{
CGContextRef currentContext = UIGraphicsGetCurrentContext();
CGContextClearRect(currentContext, rect);
CGContextSetAllowsAntialiasing(currentContext, YES);
//// Color Declarations
UIColor* color = [UIColor redColor];
UIColor* color2= [UIColor blueColor];
//// Oval Drawing
UIBezierPath* ovalPath = [UIBezierPath bezierPathWithOvalInRect: rect];
[color setFill];
[ovalPath fill];
//// triangle Drawing
UIBezierPath* trianglePath = [UIBezierPath bezierPath];
[trianglePath moveToPoint: CGPointMake(0, 0)];
[trianglePath addLineToPoint: CGPointMake(rect.size.width, rect.size.height)];
[trianglePath addLineToPoint: CGPointMake(0, rect.size.height)];
[trianglePath addLineToPoint: CGPointMake(0, 0)];
[trianglePath closePath];
[color2 setFill];
[trianglePath fill];
[color setFill];
[trianglePath fill];
}
The problem is that with drawRect, you're basically drawing on an image, and each draw method renders over the previous one. There is no culling.
To really resolve the issue, you may wish to use OpenGL, where there's only one render pass, so hidden objects aren't rendered.

Resources