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

mickm
  • 515
  • 2
  • 11
  • 20
  • possible duplicate of [UIBezierPath stroke 1px line and fill 1px width rectangle - different results.](http://stackoverflow.com/questions/11176560/uibezierpath-stroke-1px-line-and-fill-1px-width-rectangle-different-results) – jrturton Aug 27 '13 at 06:20

2 Answers2

4

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

uchuugaka
  • 12,679
  • 6
  • 37
  • 55
  • 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. – uchuugaka Aug 27 '13 at 00:19
  • 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... – mickm Aug 27 '13 at 03:52
  • 1
    So there you are running into antialiasing. The line is thiner, but not pixel aligned. see http://stackoverflow.com/questions/11176560/uibezierpath-stroke-1px-line-and-fill-1px-width-rectangle-different-results – uchuugaka Aug 27 '13 at 04:50
  • Also look at http://books.google.co.jp/books?id=L4jEdzeRa1QC&pg=PA132&lpg=PA132&dq=uibezierpath+pixel+aligned&source=bl&ots=BiighIHCKE&sig=BkpTjqAA5mOWSlNvz5eMeHemuBc&hl=en&sa=X&ei=-C8cUtSxDsmNkAXzjoDIAQ&redir_esc=y#v=onepage&q=uibezierpath%20pixel%20aligned&f=false – uchuugaka Aug 27 '13 at 04:53
  • Yup, that's it. Used to dealing with that with strings, just didn't occur to me here. Thanks! – mickm Aug 27 '13 at 17:43
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.

mbm29414
  • 11,558
  • 6
  • 56
  • 87
  • 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. – mickm Aug 27 '13 at 04:15
  • 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? – mbm29414 Aug 27 '13 at 12:32
  • 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! – mickm Aug 27 '13 at 17:45