miércoles, 4 de septiembre de 2013

Resources framework for "universal" apps

When I started programming for iOS, the projects I were involved in were all for iPad devices only (only a pack of image resources), but when I started coding I did it in such a way that with the same code it was valid for iPad and iPhone. It was a great idea because later on the iPad apps were turned into universal apps and the changes in the code were just a few details. The idea is the following:
  1. Initialize the scale of the background with respect to the current screen size and the resources dimensions and save this ratio.
  2. Scale the background and images with the previously calculated ratio. As the iPhone has not the same dimensions of the iPad, it uses scaleX and scaleY, and the images get a bit stretched.
  3. Never use points for positions, but use logic of dynamic positions with respect to the screen: top-left corner of the screen is (size.width*0, size.height*1) and the center-right point is (size.width*1, size.height*0.5).
One of the problems I found in my way was the memory constraint, the iPad 1 couldn't load big files of images. I had to change the resources target from iPad retina to iPad non-retina screen. Enabling retina display but without the -hd resources makes the graphics on iPad retina not blurred nor with pixels, so it was a good solution and saved a lot of mega bytes.

Here you have the framework and an example of the usage:

When the iPhone 5 ready apps were mandatory for new submissions (and updates), it was also possible to keep stretching the backgrounds and sprites, but now our characters have got too much fat. I had to think a new way of using only a pack of images and taking advance of all screen sizes. Pen and paper and a calculator for operations, I draw something like this:


The small rectangle should have all the important information for the app (buttons, information, ...) but the background have to fill all the space, in order to take advance of the iPhone screens. The reference size is the dimension of this rectangle in the different devices: in the iPad is the same as its size, while in the iphone will fulfill that 4*iphoneHeight = 3*iphoneWidth. Thus, the left reference point is the (screen size - reference size) / 2 and the point most on the right would be refLeft+refWidht*1.0.

Here there is the new framework and an example of how to use it: