views:

93

answers:

3

Hi, I'm trying to add a little red line on the bottom of my UIView.

I want the line to be a 1px line.

Can someone tell me why the following code:

- (void)drawRect:(CGRect)rect {
CGContextRef currentContext = UIGraphicsGetCurrentContext();
CGContextSaveGState(currentContext);
CGContextSetRGBFillColor(currentContext, 0.0f, 0.0f, 0.0f, 1.0f);
CGContextFillRect(currentContext, RECT(0, 0, rect.size.width, rect.size.height - 8));
CGContextSetLineWidth(currentContext, 1);
CGContextSetRGBStrokeColor(currentContext, 1.0f, 0.0f, 0.0f, 1.0f);
CGContextBeginPath(currentContext);
CGContextMoveToPoint(currentContext, 0, rect.size.height - 7);
CGContextAddLineToPoint(currentContext, rect.size.width, rect.size.height - 7);
CGContextStrokePath(currentContext);
CGContextRestoreGState(currentContext);

}

Draws a line that spans 2px in height?

+1  A: 

Do you use an iPhone 4? The iPhone 4 uses a coordinate system with a scale factor of 2. So you would need to set the line width to 0.5 in order to get what you want.

(The coordinate system is set up that way so the same code produces the same output on all models.)

Codo
A line that is one pixel thick on a normal display *should be* two pixels thick on a Retina display.
David M.
A: 

The integral coordinates indicate places half-way between pixels; that is, (0,0) is in the upper-left corner, above and to the left of the upper-left pixel; similarly, (1,0) is between the first and second pixels; finally, (0.5,0.5) is at the center of the upper-left pixel.

According to the documentation for CGContextSetLineWidth, "when stroked, the line straddles the path, with half of the total width on either side." Thus, if the path is lying precisely in between the pixels, the line will be stroked half on one row of pixels, half on the other.

Hence, to get a sharp pixel line, you must offset your coordinates by half a pixel: for your x coordinate, use rect.size.height - 7.5 instead of - 7.

By the way, when drawing rectangles, it is handy to use CGRectInset(rect, 0.5, 0.5) to achieve this.

David M.
A: 

Lines are by default drawn antialiased (unless you configure otherwise). Thus any line that's not strictly vertical or horizontal and starting and ending on a pixel will likely partially cover multiple pixels in some rows and/or columns, making it look like a wider grey line instead of a thin higher-contrast line.

hotpaw2
Yeah lines look like they are being antialiased, however when I turn antialiasing off, they still look that way.
almosnow