can't display 640x1136 image on iphone5 - ios

I've added a Default-568h#2x.png launch image to my app. The app needs to display a second launch image after the "real" launch image. Because the UIImage imageNamed: method doesn't automatically load the taller image the way it automatically loads retina images, I've added some code to detect the screen size and display the correct image:
-(void)pickRightImage
{
CGSize result = [[UIScreen mainScreen] bounds].size;
UIImageView *imgv = [self loadingImage];
UIImage *img;
if(result.height == 480)
{
img = [UIImage imageNamed:#"loading_screen.png"];
} else if([UIScreen mainScreen].scale == 2.f && result.height == 568) {
// iPhone 5
img = [UIImage imageNamed:#"loading_screen-568h#2x.png"];
}
[imgv setImage:img];
}
The imageView takes up the whole screen in the NIB, which is named MainWindow, and I have selected the checkbox named "Full Screen At Launch" However, the image never takes up the whole screen. (Although the launch image does.) The second image is letter boxed just as if it were a smaller image, and I had never included the tall launch image.
Is there anyway to programmatically display a full screen image on the 4 inch iphone5? Why is my image always resized?

[UIImage imageNamed:] will take care of adding the #2x for you. So you should just specify
img = [UIImage imageNamed:#"loading_screen-568h.png"];
It's also useless to test both a 4" screen AND the Retina criteria (scale = 2). All devices that have a 4" screen (568px tall) are Retina displays, so you can assume that if height == 568, the user has an iPhone 5 : replace
if ([UIScreen mainScreen].scale == 2.f && result.height == 568)
with
if ([UIScreen mainScreen].bounds.size.height == 568)
and you're good.

I tested this on the main view controller. Also, on Target > Summary > Status Bar > Visibility check "Hide during application launch".
- (void)viewDidLoad
{
[super viewDidLoad];
UIImageView *iv = [[UIImageView alloc] initWithFrame:self.view.bounds];
iv.image = [UIImage imageNamed:#"Second-default568h#2x.png"];
[self.view addSubview:iv];
}

Related

image sizes for different iOS devices

I'm new to iOS programming. I want to ask these questions about image sizes for different screen sizes
Do x, 2x and 3x image sizes suffice for all the iOS devices? I mean if I have an image named "background.png", will background.png, background2x.png and background3x.png be sufficient for all the iOS devices/screen sizes?
If not, do different iPad models require some other image sizes(other than x, 2x and 3x)? ....... A link for explaining image sizes for different screen sizes/devices will be appreciated. Thanks
yes x, 2x and 3x image sizes is necessary to develop application for all iOS devices , but the size of images can be different for iPad & iPhone devices, depending on your application UI for iPad & iPhone .
For better understanding for background images please have a look Adaptivity and Layout
One of the best article related to your query - Adaptive Layout Tutorial in iOS 9: Getting Started
If you made images for #1x, #2x, and #3x, name them like this:
iPhone 3: myImage.png
iPhone 4, 4S: myImage#2x.png
iPhone 5, 5S: myImage-568h#2x.png
iPhone 6, 6S: myImage-667h#2x.png
iPhone 6P, 6PS : myImage-736h#3x.png
Then you can just call the blow method like:
UIImage *myImage = [self deviceSizedImageWithName:#"myImage.png"];
#define kScreenHeight [UIScreen mainScreen].bounds.size.height
#define kScreenWidth [UIScreen mainScreen].bounds.size.width
#define kScreenSize [UIScreen mainScreen].bounds.size
#define IS_IPAD (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
#define IS_IPHONE (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone)
#define IS_IPHONE_4 (IS_IPHONE && kScreenHeight == 480.0f)
#define IS_IPHONE_5 (IS_IPHONE && kScreenHeight == 568.0f)
#define IS_IPHONE_6 (IS_IPHONE && kScreenHeight == 667.0f)
#define IS_IPHONE_6P (IS_IPHONE && kScreenHeight == 736.0f)
- (UIImage *)deviceSizedImageWithName:(NSString *)imageNamed
{
NSString *imgExtension = [imageNamed pathExtension];
NSString *imgName = [imageNamed stringByReplacingOccurrencesOfString:[NSString stringWithFormat:#".%#", imgExtension] withString:#""];
BOOL removedExt = [imgExtension length];
UIImage *image = [UIImage imageNamed:imageNamed];
if (IS_IPHONE_5) {
if (removedExt) image = [UIImage imageNamed:[NSString stringWithFormat:#"%#-568h.%#", imgName, imgExtension]];
else image = [UIImage imageNamed:[NSString stringWithFormat:#"%#-568h", imageNamed]];
if (!image) return [UIImage imageNamed:imageNamed];
} else if (IS_IPHONE_6) {
if (removedExt) image = [UIImage imageNamed:[NSString stringWithFormat:#"%#-667h.%#", imgName, imgExtension]];
else image = [UIImage imageNamed:[NSString stringWithFormat:#"%#-667h", imageNamed]];
if (!image) return [UIImage imageNamed:imageNamed];
} else if (IS_IPHONE_6P) {
if (removedExt) image = [UIImage imageNamed:[NSString stringWithFormat:#"%#-736.%#", imgName, imgExtension]];
else image = [UIImage imageNamed:[NSString stringWithFormat:#"%#-736", imageNamed]];
if (!image) return [UIImage imageNamed:imageNamed];
}
return image;
}

UIImagePickerController Camera view size issue

I'm building an app using the UIImagePickerController and a custom Overlay. What is does is comparing two images (before image and after image). I am using a custom overlay with the before image when taking the after photo(please see the image attached).
iPhone 5 - ios7
iPhone 4 - iOS7 (When taking the image)
iPhone 4 - iOS 7 (After taking the photo)
See the size difference between iPhone 4 and iPhone 5 camera view.
Application works fine with iPhone 5 screen size(Both ios 6 and ios7). But iPhone 4/4s screen size, it works fine ONLY with iOS6. The issue is with iphone 4/4s(ios7 ONLY), Camera view takes full screen.
That means, you can notice
iPhone 5 camera view size ~ 320*427 (iOS 6 and iOS 7)
iPhone 4 camera view size ~ 320*427 (iOS 6)
BUT
iPhone 4 camera view size ~ 320*480 (iOS 7).
After the image is taken, it fitted to the actual size of 320*427. Because of this issue, I cannot align before image with camera view on iPhone 4 iOS7 (because its screeches to 320*480).
Does anyone faces this strange issue. I tried almost everything, but NO luck. Any ideas please???
This is my piece code for loading the camera view with custom before photo overlay.
- (void)loadCameraWithImage
{
if (!isLoadedOnce)
{
isLoadedOnce = YES;
UIImagePickerController *cameraView = [[UIImagePickerController alloc] init];
cameraView.sourceType = UIImagePickerControllerSourceTypeCamera;
cameraView.wantsFullScreenLayout = NO;
if ([self respondsToSelector:#selector(setEdgesForExtendedLayout:)]) {
[self setEdgesForExtendedLayout:UIRectEdgeNone];
}
// crop before image
UIImage *imgTmpCropped = [self imageByCropping:imgBefore toRect:CGRectMake(0, 0, imgBefore.size.width/2, imgBefore.size.height)];
UIImage *overleyImage = [[UIImage alloc] initWithCGImage: imgTmpCropped.CGImage
scale: [UIScreen mainScreen].scale
orientation: UIImageOrientationDownMirrored];
UIImageView *crosshairView;
UIImageView *beforeView;
CGFloat screenHieght = [UIScreen mainScreen].bounds.size.height;
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad){
//overleyImage = [UIImage imageNamed:#"overlay_ipad.png"];
crosshairView = [[UIImageView alloc] initWithImage:overleyImage];
crosshairView.frame = CGRectMake(0, 0, 768, 1024);
[crosshairView setUserInteractionEnabled:YES];
crosshairView.backgroundColor = [UIColor clearColor];
beforeView = [[UIImageView alloc] initWithImage:overleyImage];
beforeView.frame = CGRectMake(0, 0, 384, 1024);
beforeView.alpha = 0.5;
beforeView.contentMode = UIViewContentModeScaleAspectFill;
}
else {
//overleyImage = [UIImage imageNamed:#"overleyImageAfter.png"];
crosshairView = [[UIImageView alloc] init];
beforeView = [[UIImageView alloc] initWithImage:overleyImage];
if(screenHieght>500){
crosshairView.frame = CGRectMake(0, 60, 320, 480);
beforeView.frame = CGRectMake(0, 70, 160, 427);
}
else{
if([[[UIDevice currentDevice] systemVersion] floatValue] <7.0){
crosshairView.frame = CGRectMake(0, 0, 320, 480);
beforeView.frame = CGRectMake(0, 0, 160, 427);
}
else{
crosshairView.frame = CGRectMake(0, 0, 320, 480);
beforeView.frame = CGRectMake(0, 0, 160, 480);
}
}
[crosshairView setUserInteractionEnabled:YES];
crosshairView.backgroundColor = [UIColor clearColor];
beforeView.alpha = 0.5;
beforeView.contentMode = UIViewContentModeScaleToFill;
}
//[crosshairView addSubview:beforeView];
//set our custom overlay view
cameraView.cameraOverlayView = beforeView;
cameraView.delegate = (id)self;
cameraView.showsCameraControls = YES;
cameraView.navigationBarHidden = YES;
cameraView.toolbarHidden = YES;
[cameraView setHidesBottomBarWhenPushed:YES];
[self.view.window.rootViewController presentViewController:cameraView animated:YES completion:nil];
isLoadedOnce = NO;
}
}
TL;DR
Camera's preview has the same aspect ratio in every device (4:3), screens don't. Asume the preview will have that specific aspect ratio and that it will be placed in a specific position on the screen. Draw your overlay inside that area.
Longer:
We faced the same issue. (Our use case is taking pictures of credit cards with an overlay with the same size as a card). The main problem is that the camera preview's proportions are always the same (4:3) in every device but different phones have different screen proportions (iPhone 4s vs iPhone 5, for example) so the preview's need to be fitted differently and that makes putting an overlay and cropping that very difficult.
Our solution was (the code is somewhat messy and hacky, sorry):
// Adjust camera preview to be a little bit more centered instead of adjusted to the top
CGSize screenSize = [[UIScreen mainScreen] bounds].size;
float cameraAspectRatio = 4.0 / 3.0;
float imageHeight = screenSize.width * cameraAspectRatio;
float verticalAdjustment;
if (screenSize.height - imageHeight <= 54.0f) {
verticalAdjustment = 0;
} else {
verticalAdjustment = (screenSize.height - imageHeight) / 2.0f;
verticalAdjustment /= 2.0f; // A little bit upper than centered
}
CGAffineTransform transform = self.cameraController.cameraViewTransform;
transform.ty += verticalAdjustment;
self.cameraController.cameraViewTransform = transform;
CGRect previewFrame = CGRectMake(0, verticalAdjustment, screenSize.width, imageHeight);
CardPhotoView *overlayView = [[CardPhotoView alloc] initWithFrame:CGRectMake(0, 0, screenSize.width, screenSize.height) widthPercentageOfCamera:self.widthPercentageOfCamera previewFrame:previewFrame];
self.overlayView = overlayView;
self.overlayView.delegate = self;
self.overlayView.useViewport = YES;
[self.overlayView setCameraReady:NO];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(cameraIsReady:) name:AVCaptureSessionDidStartRunningNotification object:nil];
self.cameraController.showsCameraControls = NO;
self.cameraController.navigationBarHidden = YES;
self.cameraController.toolbarHidden = YES;
self.cameraController.cameraOverlayView = self.overlayView;
[self presentViewController:self.cameraController animated:NO completion:nil];
Explanation:
self.cameraController is a UIImagePickerController. CardPhotoView is a view subclass that draws the overlay, it takes the preview frame to know exactly where the preview will be positioned (some devices will have black bars on top and bottom, some won't). It also takes a width percentage to add a little padding to the cropping window.
Also, we have hidden all default camera controls and we have implemented some buttons that will do the work for us. Those buttons are added in the CardPhotoView class and they are drawn taking into account where the preview frame is.

auto adjusting UI elements for iphone4S and iphone5

After a long search for how to display UI elements correctly on both iphone4S and iphone5.I am now confused as whats the best way to display UI elements in the Xib.Should I use autoresizing Feature in size inspector or should I use auto layout?If I use autoresizing, the image gets distorted.
Moreover ,I have also seen people doing the below
NSString *filename = #"image.png";
CGRect screenRect = [[UIScreen mainScreen] bounds];
if (screenRect.size.height == 568.0f)
filename = [filename stringByReplacingOccurrencesOfString:#".png" withString:#"-568h.png"];
self.imageView.image = [UIImage imageNamed:filename];
Can anybody assist me as how should I proceed with my problem?
I think your method is right but this code will be more cleaner way to put this.
NSString *filename;
CGRect screenBounds = [[UIScreen mainScreen] bounds];
if (screenBounds.size.height == 568) {
filename = #"image.png";
self.imageView.frame = CGRectMake(0,0,400,300);
} else {
self.imageView.frame = CGRectMake(0,0,300,300);
}
self.imageView.image = [UIImage imageNamed:filename];
And also if you want to change size of imageview accordingly to the iPhone than also you can use this code.

how to load appropriate Default.png to UImageView?

I have Default splash screens with the names:
Default-568h#2x.png, Default-Portrait.png, Default.png, Default#2x.png and so on for all types of devices.
I know that the system automatically selects the appropriate splash screen for the specific device and displays it.
The questions: is it possible to know which image the system selected? How to load the appropriate image selected by the system to the UIimageView.
I tried this:
UIImageView *splashView=[[UIImageView alloc] initWithFrame:CGRectMake(0, 0, screenWidth, screenHeight)];
splashView.image=[UIImage imageNamed:#"Default.png"];
But it loads only the image with name Default.png for all types of devices(iPhone 4, 5, iPad).
Do i need to manage it manually? I mean to load the appropriate image after identifying the device type?
I found this question after running into the same problem. Seems that if you use [UIImage imagedNamed:#"Default"]; iOS will detect retina versus non-retina and apply the #2x but it won't detect an iPhone 5 and apply the -568h
The solution I came up with was to write a category on UIImage that checks the main window's height and returns the appropriate image if it exists:
#interface UIImage (Compatible)
+ (UIImage *)compatibleImageNamed:(NSString *)name;
#end
#implementation UIImage (Compatible)
+ (UIImage *)compatibleImageNamed:(NSString *)name {
if ([[UIScreen mainScreen] bounds].size.height==568.0){
NSString *extension = [name pathExtension];
NSString *iPhone5Name = [[name stringByDeletingPathExtension] stringByAppendingString:#"-568h"];
if (extension.length!=0)
iPhone5Name = [iPhone5Name stringByAppendingPathExtension:extension];
UIImage *image = [UIImage imageNamed:iPhone5Name];
if (image)
return image;
}
return [UIImage imageNamed:name];
}
#end
Then wherever I know I want to load an image that also has an iPhone 5 version I use:
[UIImage compatibleImageNamed:#"MyImage"];
I did it manually for all splash screens:
CGRect screenRect = [[UIScreen mainScreen] bounds];
float screenWidth = screenRect.size.width;
float screenHeight = screenRect.size.height;
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) {
splashView=[[UIImageView alloc] initWithFrame:CGRectMake(0, 0, screenWidth, screenHeight)];
if (screenHeight==568.0) {
splashView.image=[UIImage imageNamed:#"Default-568h#2x.png"];//iPhone 5
}else{
splashView.image=[UIImage imageNamed:#"Default.png"]; //other iPhones
}
} else {
splashView=[[UIImageView alloc] initWithFrame:CGRectMake(0, 20, screenWidth, screenHeight-20)];
splashView.image=[UIImage imageNamed:#"Default-Portrait.png"];// iPads
}
EDIT: check this and also this out.
U how use this line to provide splash screen whether u have retina or non-retina display
UIImageView *splashView =[[UIImageView alloc] initWithImage:[UIImage imageNamed:#"Default.png"]];
Application detects device display takes image accordingly.
If device has retina display then it takes Default#2x.png automatically.
You should change this:
[UIImage imageNamed:#"Default.png"];
to
[UIImage imageNamed:#"Default"];

How to position views with CCUIViewWrapper

I am using the code from http://www.cocos2d-iphone.org/forum/topic/6889 to add a UIView to the screen in a Cocos2d game. It works great in non-retina resolution (everything is positioned correctly), but in retina resolution the UIView is placed in a different location. The code I am using to add the view to the game is basically the same as the code from the website:
UIView *myView = [[[UIView alloc] init] autorelease];
myView.backgroundColor = [UIColor redColor];
CCUIViewWrapper *wrapper = [CCUIViewWrapper wrapperForUIView:myView];
wrapper.contentSize = CGSizeMake(100, 100);
wrapper.position = ccp(50,50);
[self addChild:wrapper];
The view appears 50px from the bottom and left corner in non retina and 0px from left and 100px up in retina.
The positioning for the wrapper in retina mode is ccp(320,0). No idea why, but it works.
if ([[UIScreen mainScreen] respondsToSelector:#selector(scale)] == YES && [[UIScreen mainScreen] scale] == 2.00) {
wrapper.position = ccp(320,0); //Retina
} else {
wrapper.position = ccp(160,240); //Normal
}
The CCUIViewWrapper (at least in the form from the forum thread) does not use CC_CONTENT_SCALE_FACTOR(). That means it's not compatible with Retina displays.
You may be able to get around this by supplying properly scaled size and position, this may or may not work:
wrapper.contentSize = CGSizeMake(100 * CC_CONTENT_SCALE_FACTOR(),
100 * CC_CONTENT_SCALE_FACTOR());
wrapper.position = ccp(50 * CC_CONTENT_SCALE_FACTOR(),
50 * CC_CONTENT_SCALE_FACTOR());

Resources