Retina & non-retina compatible UIImage stacking and positioning - ios

I often need to position and stack two UIImages into an UIView.
For example, placing a picture frame around (behind) a photo, and then displaying it. Specifying the position by modifying the image's frame will not work with both Retina and non-retina devices because the hardcoded frame values will not scale.
For example, if I have a photo frame who's image is 56x56 (retina) and the actual image is 52x52 (retina), it needs to be placed at CGRectMake(2, 2, 54, 54) on top of the photo frame. But if the user is on non-retina this will fail since those values will be incorrect (they're now CGRectMake(1, 1, 27, 27)).
What is the correct way for resolution-safe image processing? Is there a way to combine two images (each with regular and #2x.pngs) that will display correctly on either screen type?

You can use UIScreen scale property. It's a readonly property. In devices prior to iPhone 4 (non-retina displays) this value will be 1.0, but with retina displays the value is 2.0. So you can store this property to a local variable, say called CGFloat scaleFactor and multiply it with the values above:
CGFloat scaleFactor=[[UIScreen mainscreen] scale];
... = CGRectMake(1.0*scalefactor,1.0*scaleFactor,27.0*scaleFactor,27.0*scaleFactor);

Related

Ios image size guide for different iphones

I am just confused about the image sizes that I need to use for buttons, image views etc.
I want to adjust images for all iphones.
What should be ratio between the screen height/width and different iphones.
Like i have a button. I have created in following way-
UIButton *takePicButton = [UIButton buttonWithType:UIButtonTypeCustom];
takePicButton.frame = CGRectMake(0, SCREEN_HEIGHT-UI_ITEM_HEIGHT, SCREEN_WIDTH, UI_ITEM_HEIGHT);
[takePicButton setBackgroundImage:[UIImage imageNamed:#"take_photo.png"] forState:UIControlStateNormal];
[self.view addSubview:takePicButton];
[takePicButton addTarget:self action:#selector(takePicture:) forControlEvents:UIControlEventTouchUpInside];
for this button what size of images I need to add on xcode to support iPhone 4 - iPhone 7.
Thanks in advance.
Here is description about how image can set in iPhone:
• 1x images are for the original iPhone through the 3GS - 'standard' resolution devices (3.5" screens)
• 2x images are for the iPhone 4 and 4S (3.5" Retina screens) and are also used for the iPhone 5, 5s,6,6s,7
• 3x images are for the new iPhone 6+,7+ (5.5" super-Retina [3x] screen)
You have to keep three different types of image into your Assets.xcassets and just provide image name at where you want to display it. It will automatically take relevant image and display it.
You can check attached screenshots. You just have to write “bgImag” and it will take relevant image from assist.
About image ration, just create image for highest resolution of iPhone (i.e iPhone 6+), and just use iConify to get rest of image assest.
Try this, u can ask for two sizes. One is SCREEN_WIDTH * 2, UI_ITEM_HEIGHT * 2, the other is SCREEN_WIDTH * 3, UI_ITEM_HEIGHT * 3.Then put two sizes pics in your Images.xcassets named xxx#2x, xxx#3x.
I want to adjust images for all iPhones.
The easy way to do that is to use layout constraints. Your code tries to do what the constraints system would, given an appropriate set of constraints, but it's less flexible because it doesn't provide for changing geometry such as when the user rotates the device.
What should be ratio between the screen height/width and different iphones[?]
Different devices have different aspect ratios. There are lots of web sites (like this one) that list the screen sizes. When possible, though, it's best not to make any assumptions about screen size. New devices may be introduced with different aspect ratios, and even a single device may appear to have different screen sizes depending on how the user chooses to use it -- things like rotation and split screen affect the size and shape of the screen real estate that your device gets to use.
for this button what size of images I need to add on xcode to support iPhone 4 - iPhone 7[?]
We can't say without knowing what your UI_ITEM_HEIGHT constant is or what relative proportions you want for your button, but you should be able to calculate that yourself if you know the various screen sizes. You can use the reference I linked above, or this one, or one of the many others out there.
Read guide line for 1x, 2x, 3x
You should simply use:
UIImage *imButton = [UIImage imageNamed:#"image.png"];
[YOURBUTTON setImage:imButton forState:UIControlStateNormal];
Xcode will automatically use the available image with scales ex: #2x or #3x
From my example your images would be:
image.png (20x20 px),
image#2x.png, (40x40 px)
image#3x.png, (60x60 px)
respectively.
Quoting from apple:
Image Size and Resolution
iOS uses a coordinate system to place content onscreen. This
coordinate system is based on measurements in points, which map to
pixels in the display. On a standard-resolution screen, one point
(1/72 of an inch) is equal to one pixel. High-resolution screens have
a higher pixel density. Because there are more pixels in the same
amount of physical space, there are more pixels per point. As a
result, high-resolution displays require images with more pixels.
Refer here
Guys
You can try below code:
if (IS_IPHONE4) {
imgHeight.constant = 150;
}
else if (IS_IPAD) {
imgHeight.constant = 300;
}
else if (IS_IPHONE5) {
imgHeight.constant = 170;
}
else {
imgHeight.constant = 200;
}
Thanks.

Creating icons and images for an iOS application with points vs pixels

I have an icon area that I used an UIImageView to display it. If the imageview has the following frame:
CGRectMake(0, 0, 20, 20)
How big (in pixels) do I make my icon for all the different iPhone display types? I know I need x.png, 2x.png and 3x.png and want them to look good in iPhone 5, 6 and 6 plus.
iOS uses points instead of pixels. So, when you create a 20x20(points) image, it is actually 20x20 pixels for regular iPhone screens where 1px = 1point. For #2x, it is like 40x40 pixels and for #3x it is like 60x60 pixels. This sizes should be sufficient to make them look good basically, as far as I know.

Creating UIView with pre-defined size in pixels

Is it possible to create a custom UIView that will be rendered on for example 1500 x 1500 pixels? I can easily create an image from a UIView and save it, my problem starts when I'm using an iPhone 5 and the image I save will be 640 x 640 px (the UIView is a square) because 640 pixel is the maximum width of it's screen resolution. So when I use the same image on a iPhone 6 Plus it will be pixelated because its screen width is 1080 x 1080 px, therefore I need to create the images that looks good on every screens. How could I manage this? Or how could I make a UIView that will be the same on every device?
In this case the result will be different based on the type of the retina screen:
CGRect newFrame = self.fullView.frame;
newFrame.size.width = 1500;
newFrame.size.height = 1500;
[self.fullView setFrame:newFrame];
I have an idea, that I would use if statements to figure out the current device and use different sizes for different devices, but a cleaner solution would be amazing. However I'm not sure that it would be the proper
logic so I welcome any other solution.
I'm saving the UIView as a UIImage with UIGraphicsBeginImageContextWithOptions(view.bounds.size, view.opaque, 0.0); so the saving method won't decrease the size.
Not sure exactly what you're trying to do but you should Auto Layout to make the view fit the correct screen size.
Also, if you want to have a specific image for each screen size you should use Asset Catalog where you can create an image set with the will load a different image for each device.

iOS image size of retina image from web service

Suppose I want an image to be 320x100 points for a retina screen, I would have to make an image 640x200 pixel and named it #2x. The problem is when I download an image from a web service of size 640x200 pixel. Normally a #2x image would be translate to size 320x100 points in the phone, but the image from the web service is still 640x200 points.
Note - the web service is my own, so I can fix it if it's the web service's problem.
Sorry If might have not worded the problem well, but this is what I meant(similar):
Retina display and [UIImage initWithData]
You'll have to set the height and width of the control in points manually and it will automatically display the image with a higher DPI without unnecesarily downscaling.
An #2x image will always be twice the dimensions of a non-retina image if it wasn't loaded through imageNamed.
Create an image like so on a retina and non-retina device:
UIImage *anImage = [UIImage imageNamed: #"anImageName"];
NSLog(#"%#: scale: %f", NSStringFromCGSize(anImage.size), anImage.scale);
The CGSize object printed on the retina device will be the same size of the non-retina image, but will have the scale set to 2.0.
Creating an image using the explicit retina suffix will reveal that the image is actually twice as big - so imageNamed does its own image scaling.
For the case where you want to display this in an already created and sized image view, you still don't need to do anything - just load it straight in and the image view will adjust the image to the correct size.
If, however, you want to create a new image view, then you'll need to create a frame paying attention to the UIScreen's resolution like so (unfortunately, you can't just set the scale property as its read only):
CGRect newFrame = CGRectZero;
newFrame.size.width = (anImage.size.width / [UIScreen mainScreen].scale);
newFrame.size.height = (anImage.size.height / [UIScreen mainScreen].scale);
This assumes that your web service is aware of wether the screen of the device is retina or not; some services will pick this up automatically, some will require you to tell them this up front. YMMV.

Retina images issues

My question is next:
How to use pixel instead point for control?
For example I add to my project retina images (size 75, 45). In this case I create UIImage with a size 37pt, 22pt (and some pixel are lost)
I create puzzle game and very important that all the pixels match my mask.
How to resolve this problem?
Thanks!
If the UIImageView size is 37x22, the image#2x size must be 74x44.
CGRect is a struct composed of CGFloat elements... So just set the sizes as 37.5 and 22.5 and you're done. Why you would want to use odd-number sized retina images though is another question - are you not supporting non-retina devices?

Resources