CGContext line width
Asked Answered
C

2

8

I'm trying to draw a simple line, the problem is that it is coming out not as 1 pixel in width but 2. The docs state that user space units will translate to a pixel, if I read it correctly.

The code is as simple as it gets, yet my line is always 2 pixels wide.

//Get the CGContext from this view
CGContextRef context = UIGraphicsGetCurrentContext();
//Set the stroke (pen) color
CGContextSetStrokeColorWithColor(context, [UIColor blueColor].CGColor);

//Set the width of the pen mark
CGContextSetLineWidth(context, 1);

for (int i = 1; i <= sections - 1; i++)
{
    UIBezierPath *path = [UIBezierPath bezierPath];
    [path moveToPoint:CGPointMake(0.0, i * kSectionHeight)];

    CGContextMoveToPoint(context, 0.0, i * kSectionHeight); //Start point
    CGContextAddLineToPoint(context, self.frame.size.width, i * kSectionHeight);
}

CGContextStrokePath(context);

enter image description here

Condorcet answered 27/8, 2013 at 0:11 Comment(1)
possible duplicate of UIBezierPath stroke 1px line and fill 1px width rectangle - different results.Ejectment
S
4

No points don't translate to pixels. If your line is too thick change the value.

Smoothshaven answered 27/8, 2013 at 0:16 Comment(5)
To expand on it. Points are device resolution independent in the API. Apple will determine what one point equals for a given apple device. Displays do not only have pixels but pixel size and spacing. Apple will determine what best represents a point on their hardware.Smoothshaven
Ok, herein lies the rub. How do I change the value? If I give a value of .5 instead of 1, the width of the line is the same, but simply a lighter shade? Must admit I'm lost here...Condorcet
So there you are running into antialiasing. The line is thiner, but not pixel aligned. see #11177060Smoothshaven
Also look at books.google.co.jp/…Smoothshaven
Yup, that's it. Used to dealing with that with strings, just didn't occur to me here. Thanks!Condorcet
S
0

I tried the following in a test app:

CGFloat desiredWidthInPixels = 1.0f;
CGFloat lineWidth = desiredWidthInPixels / [[UIScreen mainScreen] scale];
NSLog(@"lineWidth = %f", lineWidth);

I got a lineWidth of 0.5f, which should translate accurately to a single pixel width on the screen (since scale is 2.0, indicating a "Retina" device). This should adapt correctly across devices of different screen sizes.

***Caveat: Of course, this only works as long as [[UIScreen mainScreen] scale] operates as it currently does.

Sardis answered 27/8, 2013 at 2:25 Comment(3)
As I mentioned above, when I give a value of .5, the line is the same width. If, however, I use the code above and the retina version of the simulator, then the line is 1 pixel wide. So it seems to do the correct thing in a retina screen but not in a non-retina.Condorcet
On a non-retina screen, the code above should give a line width of 1.0, since scale will be 1.0. Is that not what you're seeing?Sardis
Yes, 1 on non-retina, .5 on retina. But still wasn't drawing correctly due to the anti-aliasing discussed in the post above. Thanks!Condorcet

© 2022 - 2024 — McMap. All rights reserved.