Retina simulator displays non-retina resolution - ios

In XCode, I have set my IOS simulator as iPhone (Retina 3.5-inch). However in my code, when I display the screen dimensions (using Bounds CGRect), I get 320 x 480 instead of expected 640 x 960.
Any idea why ?
I am using the latest XCode and output is named iPhone 6.1 Simulator.
Thanks.

Try this:
UIScreen *mainScreen = [UIScreen mainScreen];
UIScreenMode *screenMode = [mainScreen currentMode];
CGSize realSize = [screenMode size];

Frame and bounds are measured in points not pixels. On retina devices, 4 pixels will be in 1 point while non-retina devices have 1 pixel for every point.

Related

On iOS, why is 100 "points" a different size on different devices?

It was my understanding that if you specified a size of 100 points in iOS, that it should be interpreted as "100 density independent pixels", such that it would take up the same amount of physical space on the screen, independent of the device.
So if 2 devices had the same pixel density, each mapping 1 point to 2 pixels, 100 points would take up 200 pixels on those devices and they would appear to be the same physical size. If Device_B has 2x the pixel density of Device_A (and device A is 1:1 pixel:point) then 100 points would take up 100 pixels on Device_A, and 200 pixels on Device_B which would consume the same physical screen real-estate. Am I missing something?
I tested a UILabel of size 100x30 on an iPhone 6 and an iPad Air 2, and they definitely don't take up the same physical size on the screens - the 100x30 label on the iPhone 6 screen looks to be about 2/3 the same physical size compared to the iPad.
Here is the very simple test code
- (void)viewDidLoad {
[super viewDidLoad];
[self.view setBackgroundColor:[UIColor blueColor]];
UILabel *testLabel = [[UILabel alloc] initWithFrame:CGRectMake(20, 20, 100, 30)];
testLabel.text = #"Test Label";
testLabel.backgroundColor = [UIColor greenColor];
[self.view addSubview:testLabel];
}
I've attached an image of the 2 physical devices rendering the same label (iPad left, iPhone on right).
Ppi is pixel per inch where pixel means physical device pixels.
iOS screen scale factors 1x, 2x, 3x means only relation between physical pixels and screen points (density independent pixels). What even not 100% correct for iPhone6&7 plus where screen points rendered in x3 scale pixels and then this is downsampled with factor 1,15 to real screen pixels.
iPad Air 2 ppi = 264
iPhone 6 ppi = 326
Both have scale factor 2x. So label with size 100x30 will have size 200x60 in physical pixels on each of devices.
And
200/264 x 60/264 = 0,76 X 0,23 inches on iPad
200/326 x 60/326 = 0,61 X 0,18 inches on iPhone6

How to handle Image sizes on different devices

Currently, i am doing this type of view, What is the best way so i can manage the image in different size of scale
We have this sizes,
Device Points Pixels Scale Physical Pixels Physical PPI Size
iPhone 6 Plus 736x414 2208x1242 3x 1920x1080 401 5.5"
iPhone 6 667x375 1334x750 2x 1334x750 326 4.7"
iPhone 5 568x320 1136x640 2x 1136x640 326 4.0"
iPhone 4 480x320 960x640 2x 960x640 326 3.5"
iPhone 3GS 480x320 480x320 1x 480x320 163 3.5"
My Problem is image coming from server i want to handle this image in all type of device of Apple, I am using aspect fit in cell and when i am using 640 * 106 size then in i-phone 6plus this images are are not showing correctly size
Here's my code
CGRect frameIphone = (flag) ? CGRectMake(0, 0, self.view.frame.size.width, 106):CGRectMake(0, 0, self.view.frame.size.width, 106);
UIImageView *img = [[UIImageView alloc] initWithFrame:(iPad) ? CGRectMake(10,8,55,55) : frameIphone];
img.tag = indexPath.section;
img.contentMode = UIViewContentModeScaleAspectFit;
img.layer.masksToBounds = YES;
[img sd_setImageWithURL:[NSURL URLWithString:[objClass getImageForBackground]] placeholderImage:nil]; // URL Images
Its not that hard really, because what you doing is fixing the width/height of the view, what you need to do is calculate based on the screen ratio and give it correct height since the width is fixed based on the screen width, example if the screen is iphone 6plus, which have point of 736x414, and the image is 640x106, you do a calculation 736*109/640 (screen width * image height / image width, change with variable) = 125, thats the imageView height you should use, not 106 directly
You can set the image to the image view first then config it's frame also ok, so you can get the image height/width

Xcode asset catalog support for 3.5", 4", and 4.7" #2x images?

Xcode offers asset buckets for 1x, 2x, 4" 2x, and 3x assets. My fullscreen assets are all wonky with this configuration, because the 2x bucket is used for 3.5" and 4.7" screens. Currently I have a UIImage category that introspects the current screen size, and selects a "*-3.5" asset if the device seems to be 3.5".
This is clunky and not cool. Seeing that Xcode caters to all the different device sizes for their LaunchImage asset, I was hoping there was some way to supply device specific assets for non launch image assets without resorting to code.
I have reported a bug to Apple about this since mid November 2014 and I just noticed they marked it as No Value... which gives me the impression Apple has omitted an additional slot for iPhone 6 on purpose. My guess is they now want the 2x slot to be used for iPhone 6, and maybe they're reducing support to iPhone 4s as it's getting old.
If you really want to keep supporting the iPhone 4s, I'd suggest to use iPhone 6 sized images in the 2x slot, and then use the following method to load your images:
+(UIImage *)loadImageNamed:(NSString *)imageName
{
CGSize screenSize = [UIScreen mainScreen].bounds.size;
CGFloat screenHeight = MAX(screenSize.width, screenSize.height);
CGFloat const IPHONE_4_SCREEN_HEIGHT = 480;
UIImage *image = [UIImage imageNamed:imageName];
if(screenHeight == IPHONE_4_SCREEN_HEIGHT) {
CGFloat const xScale = .85333333;//x conversion ratio from iPhone 6's 375 pts width screen to iPhone 4's 320 pts width screen
CGFloat const yScale = .71964018;//y conversion ratio from iPhone 6's 667 pts height screen to iPhone 4's 480 pts height screen
CGSize newSize = CGSizeMake(xScale * image.size.width, yScale * image.size.height);
UIGraphicsBeginImageContextWithOptions(newSize, NO, 0);
[image drawInRect:(CGRect){0, 0, newSize}];
UIImage *resizedImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return resizedImage;
}
return image;
}
Resizing a big image (iPhone 6) to a smaller one (iPhone 4) doesn't lose much quality even if the aspect ration is not the same.
Using an existing project when moving to Xcode 6 and iOS 8 creates some initial issues. I solved this by changing the image set from Device specific to Universal. This removes the R4 image option and leaves you with #1x, #2xand #3x. If you use for example a background image that needs to fit the screen then I will recommend that you find an image that does not have to fit 100 % perfect to look good, and set image to be displayed as Aspect Fill.
I have the same problem and got confirmation from apple that I have to wrote code for that. For example you can try like this Fullscreen images on iPhone 6 with Asset Catalogs
But I actually went lazy about it by using one 2x for 4" & 4.7" screen and another 2x for 3.5" screen

xcode 6 is iphone 5 no longer 568 points in height?

So I'm trying to update my game to fit the iPhone 6 properly and i see now that when i run my game on the iPhone 5 simulator, everything is fitting as if it were an iPhone 4. I use if statements to determine the height of the device:
if ((int)[[UIScreen mainScreen] bounds].size.height == 568)
{
mylabel4.fontSize = 35;
mylabel4.position = CGPointMake(CGRectGetMidX(self.frame) -145, CGRectGetMidY(self.frame) -130);
} else {
mylabel4.fontSize = 35;
mylabel4.position = CGPointMake(CGRectGetMidX(self.frame) -110, CGRectGetMidY(self.frame) - 130);
}
And like i said when i run the iPhone 5 simulator, it runs the code in the 'else' bracket. Its like the iPhone 5 is no longer 568 points in height. This was working fine until i download Xcode 6? What's going on here?
The UIScreen bounds behavior has changed in iOS8. Previously it would always give you width and height of the screen in portrait (so 320 x 568 on the iPhone 5), but in iOS8 it will give you width and height with respect to whatever orientation you're in, i.e. in landscape you would get 568 x 320.
If you want to get the bounds in portrait (like before), use:
[UIScreen mainScreen].fixedCoordinateSpace.bounds.size
Just add launch images for the iPhone and the simulator will display the proper points. Weird bug.

Migrate issues to iphone 5 resolution

I am using XCode 4.5.1 and iOS Simulator (Retina 4 inch)
I have project that I made one yera ago. So now I want to migrate my project to new resolution.
My problem is next:
I integrate code into my project to detect which resolution I have.
CGRect screenBounds = [[UIScreen mainScreen] bounds];
But after I out value of screenBounds to NSLog I got width = 320 and height = 480, but I exprected to see 1136 × 640.
Have you got the same issues?
Are you sure you are using the 4inch simulator? [[UIScreen mainScreen] bounds] will return the screen bounds in points, not pixels. So in the 4inch iPhone the CGRectreturned should be 320x568.
So if you call [[UIScreen mainScreen] bounds]:
<= iPhone 3GS: 320x480
iPhone 4 & iPhone 4S: 320x480
iPhone 5: 320x568
NOTE: If you didn't add the Default-568h#2x.png file, and the app runs letterboxed the method you used will return the iPhone 4 & 4S values.
TIP: To determine whether you are using an iPhone 5 or the rest, this code may come handy:
#define IS_IPHONE_5 ( fabs( ( double )[ [ UIScreen mainScreen ] bounds ].size.height - ( double )568 ) < DBL_EPSILON )
if( IS_IPHONE_5 )
{
// iPhone 5
}
else
{
// Other
}
To adapt your app to the new taller screen, the first thing you do is to change the launch image to: Default-568h#2x.png. Its size should be 1136x640 (HxW). Yep, having the default image in the new screen size is the key to let your app take the whole of new iPhone 5's screen.
Also, you'll have to take a few more steps:
Make sure, your Xibs/Views use auto-layout to resize themselves. Use springs and struts to resize views. If this is not good enough for your app, design your xib/storyboard for one specific screen size and reposition programmatically for the other.

Resources