0

I have a two-dimensional table in my app and I want to have a 1 pixel thick border around each cell. Each cell is a distinct UIView and I found that I can draw such borders with something like:

dataCell.layer.borderWidth = 0.5; // repeat for each cell
tableContainer.layer.borderWidth = 1.0; // do once for the entire table

That was good for both retina and non-retina devices. However now I want to render my table into an image first before displaying it, and on non-retina devices the result looks like this:

Blurry cell dividers

The table's border is fine, but the individual cell borders got blurry. The method I use for converting the whole thing to image is:

- (UIImage *)getImage {
    UIGraphicsBeginImageContextWithOptions(self.bounds.size, NO, [[UIScreen mainScreen]scale]);
    [[self layer] renderInContext:UIGraphicsGetCurrentContext()];
    UIImage *viewImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return viewImage;
}

That's a category on UIView. The reason I want to display this as an image is because when the device is rotated, the resulting animation looks much better when the whole table is a single static object, otherwise all the subviews become de-coupled from each other and animate along different trajectories into their final positions.

What can I do to fix this blurriness?

Edit:

While it's true that you cannot truly display lines smaller than 1 pixel, in practice there are two things that could make this work. First of all, on retina screens 0.5 "logical" pixels is exactly 1 real pixel and iOS renders is perfectly fine in that case.

On non-retina devices the iOS does something different: when I ask for 0.5px border all around a view, it draws a 1px border at the left and bottom of the view. When I put many such views side by side in a grid, the result is actually very sensible - I get a 1px border between the views.

Here is a screenshot of a non-retina rendition of 0.5px borders around the white cells, right side of which is missing (I typically just add a 1px border around the entire container to fix that). This is without turning it into an image.

0.5px border

I thought that UIGraphicsGetCurrentContext() will do a WYSIWYG kind of rendering and give me an image that is exactly like what would render on screen otherwise. Is there any way to trick it to do that?

SaltyNuts
  • 5,068
  • 8
  • 48
  • 80
  • What happens if you change the borderWidth of the dataCell to 1.0 ? – Petar Mar 13 '13 at 10:24
  • I'm not an expert in Core Graphics, but I don't think it's possible to have a line less than one "physical" pixel wide. – Kreiri Mar 13 '13 at 10:28
  • It's not possible to have less than 1 real pixel, but as I explain in the additional info above, it's possible to combine several sub-pixel sized elements into a way that makes sense. As for using borderWidth of 1.0 - because the borders are inset into the view, the result is that the total border width is 2.0 pixels between two adjacent cells. – SaltyNuts Mar 13 '13 at 14:02

0 Answers0