I've seen various old posts regarding image sizes, but I can't find anything up-to-date or even know if it's possible with just asset catalog to provide images for all iPad and iPhone screen sizes.?
This is the best post I've found, but in Xcode 7 it doesn't show "Retina 4 2x" or the iPhone 6 / 6+
Xcode 6 - xcassets for universal image support
In xcode 7 there is a universal option, but the three images don't support all the device sizes.
I've seen options where you can provide your own images outside of asset catalog, but I'd really like to use asset catalog.
How to use xcassets/universal background images for different iPhones/iPads?
EDIT: It looks like I might have to go for the none asset catalog route :(
A)
I'd like to future proof this solution, so it falls back and if needs be, resize the most appropriate image, as-is I'm not sure will happen.
NSNumber *screenWidth = @([UIScreen mainScreen].bounds.size.width);
NSString *imageName = [NSString stringWithFormat:@"name-%@w", screenWidth];
UIImage *image = [UIImage imageNamed:imageName];
B)
Or maybe this code is better? Although I'm not sure what sizes this relates to, it's also a bit out of date as it doesn't support x3 images ?
#import <UIKit/UIKit.h>
@interface UIImage (DefaultImage)
// uses statusbar orientation
+ (UIImage *)defaultImage;
//uses given orientation
+ (UIImage *)defaultImageForOrientation:(UIInterfaceOrientation)orient;
@end
@implementation UIImage (DefaultImage)
+ (UIImage *)defaultImage {
return [self defaultImageForOrientation:[[UIApplication sharedApplication] statusBarOrientation]];
}
+ (UIImage *)defaultImageForOrientation:(UIInterfaceOrientation)orient {
// choose the correct launch image for orientation, device and scale
NSMutableString *launchImageName = [[NSMutableString alloc] initWithString:@"Default"];
BOOL isPad = ( UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad );
if ( isPad ) {
BOOL isLandscape = UIInterfaceOrientationIsLandscape(orient);
NSString *imageOrientation = (isLandscape) ? @"Landscape" : @"Portrait";
BOOL isRetina = ([[UIScreen mainScreen] respondsToSelector:@selector(scale)] && [[UIScreen mainScreen] scale] == 2.0);
NSString *scaleString = (isRetina) ? @"@2x" : @"";
// Default-Landscape~ipad.png
// Default-Landscape@2x~ipad.png
// Default-Portrait~ipad.png
// Default-Portrait@2x~ipad.png
launchImageName = [NSMutableString stringWithFormat:@"%@-%@%@.png", launchImageName, imageOrientation, scaleString];
} else {
if ( CGRectGetHeight([UIScreen mainScreen].bounds) > 480.f) {
// Default-568h.png
launchImageName = [NSMutableString stringWithFormat:@"%@-568h.png", launchImageName];
} else {
// Default.png
// Default@2x.png
launchImageName = [NSMutableString stringWithFormat:@"%@.png", launchImageName];
}
}
return [UIImage imageNamed:launchImageName];
}
@end
Disclaimer: taken from https://github.com/Daij-Djan/DDUtils
C)
This also looks good, but it's re-sizing and not using actual sharp images and there's no fall back.
https://gist.github.com/kevindelord/fe2e691d06ab745fbb00
NSString *extension = @""; // iPhone 3GS and earlier
if (scale == 3.f) {
extension = @"@3x"; // iPhone 6 Plus
} else if (scale == 2.f && h == 568.0f && w == 320.0f) {
extension = @"-568h@2x"; // iPhone 5, 5S, 5C
} else if (scale == 2.f && h == 667.0f && w == 375.0f) {
extension = @"-667h@2x"; // iPhone 6
} else if (scale == 2.f && h == 480.0f && w == 320.0f) {
extension = @"@2x"; // iPhone 4, 4S
} else if (scale == 1.f && h == 1024.0f && w == 768.0f) {
extension = @"-512h"; // iPad Mini, iPad 2, iPad 1
} else if (scale == 2.f && h == 1024.0f && w == 768.0f) {
extension = @"-1024h@2x"; // iPad Mini 3, iPad Mini 2, iPad Air, iPad Air 2
}
return extension;
I just modified the Contents.json file and added the Retina 4 2x:
And the Retina 4 2x appeared back in Assets Catalog for that image set :)
To provide different images for iPhone and iPad you just need to select the iPhone and iPad check boxes under the Devices section and deselect the Universal one.
However I still don't know how to handle the iPhone 6. I always had a different image set for iPhone 6 with just one image and checked in the code if the device is an iPhone6 or iPhone6 Simulator and set that image instead.