I made this game. Right now the game supports all iOS devices except iPhone 5.
The definition of each level of the game is kept in a plist. The creation of each level is done through a graphical level editor. Each device family has its own plists. So, right now the game has 100 levels and 200 plists; 100 plists for the iPhone family and 100 plists for the iPad family.
In order to support the iPhone 5 I need to create 100 new plists and adjust the plists accordingly, which is time consuming, not to mention the creation of new levels...
The editor for creating and editing the levels is solely based on the manipulation of UIViews that describe the game elements. So, this is the code that I wrote to save and restore the state of each UIView in one level of the game.
- (void)encodeWithCoder:(NSCoder *)aCoder {
// Save the screen size of the device that the view was saved on
[aCoder encodeCGSize:self.gameView.bounds.size forKey:@"saveDeviceGameViewSize"];
// ****************
// ALL properties are saved in normalized coords
// ****************
// Save the center of the view
CGPoint normCenter = CGPointMake(self.center.x / self.gameView.bounds.size.width, self.center.y / self.gameView.bounds.size.height);
[aCoder encodeCGPoint:normCenter forKey:@"center"];
// I rely on view bounds NOT frame
CGRect normBounds = CGRectMake(0, 0, self.bounds.size.width / self.gameView.bounds.size.width, self.bounds.size.height / self.gameView.bounds.size.height);
[aCoder encodeCGRect:normBounds forKey:@"bounds"];
// Here I save the transformation of the view, it has ONLY rotation info, not translation or scalings
[aCoder encodeCGAffineTransform:self.transform forKey:@"transform"];
}
- (id)initWithCoder:(NSCoder *)aDecoder {
self = [super initWithCoder:aDecoder];
if (self) {
// Restore the screen size of the device that the view was saved on
saveDeviceGameViewSize = [aDecoder decodeCGSizeForKey:@"saveDeviceGameViewSize"];
// Adjust the view center
CGPoint tmpCenter = [aDecoder decodeCGPointForKey:@"center"];
tmpCenter.x *= self.gameView.bounds.size.width;
tmpCenter.y *= self.gameView.bounds.size.height;
self.center = tmpCenter;
// Restore the transform
self.transform = [aDecoder decodeCGAffineTransformForKey:@"transform"];
// Restore the bounds
CGRect tmpBounds = [aDecoder decodeCGRectForKey:@"bounds"];
CGFloat ratio = self.gameView.bounds.size.height / saveDeviceGameViewSize.height;
tmpBounds.size.width *= (saveDeviceGameViewSize.width * ratio);
tmpBounds.size.height *= self.gameView.bounds.size.height;
self.bounds = tmpBounds;
}
return self;
}
I am really stuck here. I cannot explain what is wrong with this code. The UIViews are correctly positioned when restored on the same device. This is not true when the level is opened on another device. There are slightly misplaced elements and distortions.
Here are two pairs of screenshots demostrating the issues:


What is the correct approach to handle the scaling of the levels on different screens? Should I rely on AutoResizingMasks (I need to support iOS 4 and later)? In any case I would like to give a solid paradigm on how to achieve this.
Thanks