Usage of retina images and setting an UIImageView - objective-c

It is the first time that I need to use images with the name formats of like: #2x and -568h#2x But I do not understand when the -568#2x is used. This should be for iPhone 5 and up but, the image is not used on my iPhone 5S when testing.
I tried very hard searching for this problem, but I cannot find it.
Problem:
Only the #2x image is used on all devices, and the -568#2x is ignored totally. So there is a gap above my image on screen while I have set the UIImageView in Storyboard to fill the whole screen. So in my understanding, with the setImage it would look first in the Project folder, and then to the Asset Catalog. But still it does not take the -568#2x image and always take the #2x image.
I have also set the auto layout right for the UIImageView so it would fit top, bottom, left, right.
Code/Screen:
So I have 2 images in my Project folder as you can see on the image:
Link to image
Here is the gap on top:
Link to image
And then in my code I use this code for setting the image on my Outlet:
[[self image] setImage:[UIImage imageNamed:#"firstLaunch"]];
So what could be the problem? Am I totally wrong how the Automatic image names thingy is working?
Thanks!

You could do something like this:
CGRect screenBounds = [[UIScreen mainScreen] bounds];
if (screenBounds.size.height == 568) {
self.view.layer.contents = (id)[UIImage imageNamed:#"firstLaunch#R4"].CGImage;
} else {
self.view.layer.contents = (id)[UIImage imageNamed:#"firstLaunch#2x"].CGImage;
}

Related

Trying to add a new background in iPhone 5 4" storyboard

I am trying to add a correct sized background image to support iPhone5 4" screen but i am still getting the same letterbox in the bottom. The image is correct sized image.
The code i use:
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone) {
CGSize result = [[UIScreen mainScreen] bounds].size;
if(result.height == kIphone5) {
//====THIS IS AN iPhone5 4" screen====//
UIImage *image = [UIImage imageNamed:#"iphone_frosty-568h#2x.png"];
[backgroundImage setImage:image];
}
I do have the lanch image in place..
UPDATE
I ended up adding the iPhone5 background image to the iPhone5 Storyboard and use that for all iPhone modes. Do not know if that is a correct way of doing this but it seems to work.
Can someone please advice?
Are you just talking about making your app run using the full screen on an iPhone 5 (getting rid of the letterbox)? If so, you don't use the new image size as a background image somewhere in code; you have to add it to your project file as a launch image. See the Launch Images section of the Apple docs for more info.

set retina image in uiimageview

today i first run my app on my iphone but all my images (my background image too) were blurry, i read in the apple documentation and i understand that i should use a double pixel size (640X960 instead of 320X460). to set my image background i just use an uiiamgeview and set the image in the xib file. now, my question is how can i set the image from the .m file and not from my xib file. when i try to set the image from the .m file my image was much bigger then my uiimageview (i see only part from the image)?
thanks!
When using retina double sized images you don't actually have to do anything as far as loading them in code or in Interface Builder.
You just need to name the properly and make sure they're in your Xcode project.
For example if you had one image.png you'd need an image#2x.png in your Xcode project as well. iOS will automatically use the correct when when displaying on a Retina Device.
Update: In response to your comment.
This will create an UIImageView and set it to the size of the view. Its very similar to how most people do it in Interface Builder.
- (void)viewDidLoad
{
UIImageView *background = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"background.png"];
[background setFrame:CGRect(0.0,0.0,self.view.frame.size.width,self.view.frame.size.height)];
[self.view addSubview:background];
}

Problems scaling a UIImage to fit a UIButton

I have a set of buttons and different sized images. I want to scale each image in order that it fits the button in the correct aspect ratio. Once I've scaled the image, I set the button's image property to the scaled version.
UIImage *scaledImage = [image scaledForButton:pickerButton];
[pickerButton setImage:scaledImage forState:UIControlStateNormal];
my scaledForButton method is defined in a class extension for UIImage. It looks like this:
- (UIImage *)scaledForButton:(UIButton *)button
{
// Check which dimension (width or height) to pay respect to and
// calculate the scale factor
CGFloat imageRatio = self.size.width / self.size.height;
CGFloat buttonRatio = button.frame.size.width / button.frame.size.height;
CGFloat scaleFactor = (imageRatio > buttonRatio ? self.size.width/button.frame.size.width : self.size.height/button.frame.size.height);
// Create image using scale factor
UIImage *scaledimage = [UIImage imageWithCGImage:[self CGImage]
scale:scaleFactor
orientation:UIImageOrientationUp];
return scaledimage;
}
When I run this on an iPad2 it works fine and the images are scaled correctly. However if I run it on a retina display (both in the simulator and on a device) the image does not scale correctly and is squished into the button.
Any ideas why this would happen on retina only? I've been scratching my head for a couple of days but can't figure it out. They're both running the same iOS and I've checked the scale and ratio outputs, which are always the same, regardless of device. Many thanks.
Found the answer here: UIButton doesn't listen to content mode setting?
If you're setting the .contentMode, it seems you have to set the imageView property of the UIButton, not just the UIButton, then it worked properly.
The problem on iPad 3 was as Herman suggested - the CGImage was still a lot larger than the UIButton, so even though it was scaled down, it still had to be resized to fit the button.

How to handle autoresizing on UIButton elements which has been created dynamically

I create some buttons dynamically on my view and i decide their frames according to some of my JSON respone parameters. But i want to autoresize them when the device(dsimulator) rotates. I can easily do this on interface builder but can't do anything on dynamic ones. Can someone help?
EDIT
Here is a snipped of my code
if (button.tag==1) {
button.frame = CGRectMake(30.0f, yPosition, 200.0f, buttonHeight);
}
if (button.tag==2) {
button.frame = CGRectMake(280.0f, yPosition, 200.0f, buttonHeight);
}
if (button.tag==3) {
button.frame = CGRectMake(530.0f, yPosition, 200.0f, buttonHeight);
}
There is no problem when using Portraid mode but when it rotates to Landscape a big empty area stays on the right side of the screen. How can i fix this?(I mean, when i rotate, i want the buttons got to the center of the scren's width)
EDIT:
I played with autoresizing on Size Inspector(Xcode 4.3) with my xib file and it works great, but whatever i did i couldn't resize the dynamically created buttons after rotation. I tried almost all of AutoresizingMask enums of UIView but nothing changes. Can someone please help
You can define by code what was the expected behavior when the device is rotated.
You can take a look at: http://developer.apple.com/library/ios/#documentation/uikit/reference/uiview_class/uiview/uiview.html
and
http://developer.apple.com/library/ios/#documentation/uikit/reference/uiview_class/uiview/uiview.html#//apple_ref/c/tdef/UIViewAutoresizing
You need to set the button behavior when you add it like:
[button setAutoresizingMask:UIViewAutoresizingFlexibleBottomMargin];
The attributes you've set up in your interface builder file are the UIViewAutoresizing attributes.
Take a look at this documentation from Apple on the UIView class (which your button is a subclass of); look for the UIViewAutoresizing attribute. That's the one you'll want.
Update: Here's a snippet of code for an MKMapView that uses this ability:
mainMapView = [[MKMapView alloc] initWithFrame:CGRectMake(20, 239, 280, 122)];
[mainMapView setAutoresizingMask:UIViewAutoresizingFlexibleTopMargin];
With UIViewAutoresizingFlexibleTopMargin, the map view moves down when the user answers the phone --- it fixes the map's position relative to the top of the screen.
Dig around in the documentation and you'll find the autoresizing mask that works best for your situation.

How to animate an image onto the screen

I am new to Objective-C and I want to let a screenshot made with
CGSize imageSize = [[UIScreen mainScreen] bounds].size;
...
UIGraphicsBeginImageContext(imageSize);
...
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
"fly in" (rotating and stoping in random angle) inside an own image container, looking like a small photo (shadow, white border). how could I realize that?
Since you have a vague question - and your code shows only how you are getting the screen image - here's a general answer.
Put the image on a CAImageLayer
Add a border or a shadow or whatever other chrome you need to your image layer (or on another layer underneath it)
Use Core Animation to animate this CAImageLayer to whatever position or state you want it to be in.
You can accomplish it with OpenGL ES.
Here is a great project which provides generic base OpenGL ES view transition class.
https://github.com/epatel/EPGLTransitionView
There are several predefined transitions, you can take as an example https://github.com/epatel/EPGLTransitionView/tree/master/src
Demo3Transition actually shows how to rotate the screenshot
https://github.com/epatel/EPGLTransitionView/blob/master/src/Demo3Transition.m
You can view available transitions in actions if you launch DemoProject.