I’m building a UIBezierPath as follows:
UIBezierPath *path = [UIBezierPath bezierPath];
CGFloat yOrigin = 2;
for (int i = 0; i < lines; ++i) {
[path moveToPoint:CGPointMake(0, yOrigin)];
[path addLineToPoint:CGPointMake(width, yOrigin)];
yOrigin += distance;
}
[path closePath];
I then put it in a CAShapeLayer:
CAShapeLayer *shapeLayer = [[CAShapeLayer alloc] init];
[shapeLayer setFrame:aFrame];
[shapeLayer setPath:[bezierPath CGPath]];
[shapeLayer setStrokeColor:[[UIColor blackColor] CGColor]];
[shapeLayer setMasksToBounds:YES];
However, when added to my scroll view, here is the result:

Why does it do this? The first four lines are gray, almost! It looks like an aliasing problem, but the path is so straightforward.
Yes this is an antialiasing problem.
The path you use has a width of 1 pt. In the above example the upper three instances of the CAShapeLayer are positioned exactly centered on a whole point value eg. 5.0, where the lower instance is positioned between two whole points eg. 14.5.
When the system renders your Layers to the screens pixels it antialiases the first three lines, drawing both touched pixels with 50% transparency. The lower line perfectly sit on a pixel and is therefore drawn in perfect black.
I hope a little ASCII Art helps understanding.