iOS - Pixel misalignment, why it's bad, how to fix it...
One of the common things I see going wrong is pixel alignment.
What is pixel mis-alignment, what’s causing it, and how to fix it?
Read on for more details.
A screen is built up of pixels. Each and every pixel is distinct and can be addressed with an exact coordinate. Before there were retina screens, every pixel consisted of an x and y integral value in the range of 320 by 480.
When Retina came around, there were actually 640 x 960 pixels available. But to keep current Apps working, Apple still addresses these pixels in the range of 320 by 480. But there were pixels available at every exact .5 increment.
When it comes to rendering, in a perfect world, every pixel you request the system to draw to the screen will line up perfectly with an actual physical point on the device’s screen. When you start doing calculations to create relative drawing positioning on-screen you can easily calculate values that do not line up nicely with a multiple of .5. And thus pixel mis-alignment will occur.
Another common reason for pixel misalignment is when the graphical assets you are using for a retina version of an image is not exactly twice the dimensions of the non-retina image. An icon which is 30x30 on non-retina and 61x60 in retina version is quite common. But, this causes pixel mis-aligment as well.
How to detect pixel mis-alignment?
Instruments and Simulator will help you here. If you run your app in the Simulator you can enable an option called „Color misaligned images” it is within the Debug menu of the simulator. When you enable this option, Simulator will color the items on your screen to indicate certain things happening. A yellow tint is no problem, that is an indication of something being stretched, the iOS platform does this extensively to reduce memory usage. But when items appear magenta colored, it’s an indication of a problem. And in my opinion it’s a problem you absolutely have to fix.
Image misalignment degrades rendering performance significantly on iOS. This happens because a misaligned image needs to be interpolated with it’s surrounding pixels to determine what color values actually have to be sent to the screen buffer.
How to fix pixel misalignment?
Once you have found your culprit. It’s a good idea to start looking through your code to determine how the actual frame of the misaligned screen item is calculated. Some debugging will help you here. I’d look in any layoutSubviews or loadView calls for any divisions being performed on view frames. Also using Font metrics in your calculations is a common cause for misaligned images.
Most likely you will have found your culprit pretty soon. How to fix this? There are two ways to go about this. Either use a floorf or ceilf on the exact value causing the misalignment. Or pass the CGRect for the views frame through a CGRectIntegral call.
When it concerns an image on a retina device, make sure the retina version of that image is actually exactly twice the dimensions of the non retina image. Faulty dimensions on retina image resources is a common cause as well for pixel misalignment. So get check those image resources if they show up magenta.