UITabBarItem Image Size - ios

I am making images for my UITabBar. I am making them of size 60x60, because that's what retina screens use. However, when I use that size, it shows up too big in the bar, so you can only see part of the image. When I reduce it down to 30x30, it works, but that size is supposed to be for non-retina displays. Why does it not show up properly when I use 60x60?

You probably may have to rename your retina image to imagename#2x.png.

You were getting this behavior because you were supplying a high-resolution image, when iOS was looking for a standard resolution image.
iOS automatically selects the appropriate image size for you, depending on the resolution of the accessing device. So you will be responsible for supplying a "standard resolution" image, for non-retina devices, and a "high resolution" image, for retina displays. The way you do this in iOS is to append "#2x" to the end of your filename, but before the file extension, like this:
my-image.png // for non-retina displays (Ex: 30x30 dpi)
my-image#2x.png // for retina displays (Ex: 60x60 dpi)
my-image#3x.png // for retina displays(plus editions) (Ex: 90x90 dpi)
Then, when you are referencing files in your XCode project, you only need to supply the filename to the standard resolution (e.g, "my-image.png") and if the accessing device has a retina display, then XCode will automatically select the file with the "#2x" suffix for you. This is very convenient, because it saves us developers from having to detect whether or not the device has a retina display, and which image we need to supply.
Here is a code example:
// Select an image named "my-image.png"
UIImage *img = [UIImage imageNamed:#"my-image.png"];
// If the device this code is run on is a retina device,
// then Xcode will automatically search for "my-image#2x.png" and "my-image#3x.png"
// otherwise, it will use "my-image.png"
You can read more on the subject via the Apple Developer's Site: Optimizing for High Resolution

Related

Xcode #2x image suffix not showing as Retina in iOS

I am having difficulties with retina images.
The screenshot below shows the UICollectionView with a UIImageView contained within each UICollectionViewCell.
Within the app I have a large image 512x512 pixels called travel.png.
The green circle shows what is displayed on the app when I name this file: travel.png. The blue circle shows what I see when I update the image name to be travel#2x.png (i.e. retina naming).
I was hoping due to the large size of the image (512x512) that simply adding the #2x suffix would be enough to convert it to twice the definition (i.e. retina) but as you can see from the two screenshots, both version images show as non-retina.
How can I update the image so that it will display in retina?
travel.png:
travel#2x.png:
* Updated *
Following request in comments below:
I load this image by calling the following function:
// Note - when this method is called: contentMode is set to .scaleAspectFit & imageName is "travel"
public func setImageName(imageName: String, contentMode: ContentMode) {
self.contentMode = contentMode
if let image = UIImage(named: imageName) {
self.image = image
}
}
Here is how the image appears in Xcode before the app renders it (as you can see it is high enough definition):
The reason why you see the low quality image is anti-aliasing. When you provide images bigger then an actual frame of UIImageView (scaleAspectFit mode) the system will automatically downscale them. During scaling some anti-aliasing effects can be added at curve shapes. To avoid the effect you should provide the exact image size you want to display on the screen.
To detect if UIImageView autoscale the image you can switch on Debug->Color Misaligned Images at Simulator menu:
Now all scaled images will highlight at simulator with yellow color. Each highlighted image may have anti-aliasing artifacts and affect CPU usage for scaling algorithms:
To resolve the issue you should use exact sizes. So the system will use them directly without any additional calculations. For example, if your button have 80x80px size you should add three images to assert catalog with following sizes and dpi: 80x80px (72 dpi), 160x160px (144 dpi) and 240x240px (216 dpi):
Now the image will be drawn at the screen without downscaling with much better visual quality:
If your intention is to have just one image for all the sizes, I would suggest it having under Assets.xcassets. It is easy to create the folder structures and manage media assets here.
Steps
On clicking + icon, you will displayed a list of actions. Choose to create a New folder.
Choosing the new folder that is created, click on the + icon again and click on New Image Set.
Choose the imageset. And choose the attributes inspector.
Select Single Scale, under Scales.
Drag and drop the image.
Rename the image name and folder names as you wish.
Now you can use this image using the image name for all the screen sizes.
TL;DR;
Change the view layer's minificationFilter to .trilinear
imageView.layer.minificationFilter = .trilinear
as illustrated by the device screenshot below
As Anton's answer correctly pointed out, the aliasing effet you observe is caused by the large difference in dimensions between the source image and the image view it's displayed in. Adding the #2x suffix won't change anything if you do not change the dimensions of the source image itself.
That said there is an easy way to improve the situation without resizing the original image: CALayer offers some control over the method used by the graphics back-end to resize images : minificationFilter and magnificationFilter. The first one is relevant in your case since the image size is being reduced. The default value is CALayerContentsFilter.linear, just switch to .trilinear for a much better result (more info on those wikipedia pages). This will require more GPU power (thus battery), especially if you apply it on many images.
You should really consider resizing the images before displaying them, either statically or at run-time (and maybe cache the resized versions). In addition to the bad visual quality, using such large images in quantities in your UI will decrease performance and waste lots of memory, leading to potentially other issues.
I have fixed, #DarshanKunjadiya issue.
Make sure (if you are already using assets):
Make sure images are not un-assigned
Now use images in storyboard or code without extensions. (e.g. "image" NOT "image.png")
If you are not using images from assets, move them to assets.
Demo Projects
Hope it helps.
Let me know of your feedback.
I think images without the #2x and #3x are rendered for devices with low resolutions (like the iphone 4 an 3G).
The solution I think is to always use the .xcassets file or to add the #2x or #3X in the names of your images.
In iOS, content is placed on the screen based on the iOS coordinate system. for displaying an image on a standard resolution system having 1:1 pixel density we should supply image at #1x resolution. for higher resolution displays the pixel density will be a scale factor of 2.0, 3.0 which refers in the iOS system as #2x and #3x respectively. That is high-resolution displays demands images with higher density.
For example, if you want to display an image of size 128x128 in standard resolution. You have to supply the #2x and #3x size image of the same. ie., 256x256 at #2x version and 384x384 image at #3x version.
In the following screenshot, I have supplied an image of size 256x256 for 2x version to display a 128x128 pixel image in iPhone 6s. iPhone 6s render images at #2x size. Using the three version of images such as 1x, 2x and 3x with asset catalogue will resolve your issues. So the iPhone will automatically render the correct sized image automatically with the screen resolution.

Size of image to set as Background image in view controller

I am trying to put a background image on a UIViewController.However i cannot figure out the size needed because the image should support devices from iphone 4s to iPAD...Here are few questions:
1) Should i put those large image on image xcassets on 1x,2x,3x size,if so what should be the size of those images?
2) Or Should i Copy a high resolution image on the bundle itself again if so what should be the size?
We have differnet-2 sizes in assets like here:
(Only for iPhones)
What I found is that, you should opt for first option and 750X1333, 1080X1920 and 1242X2208 should be the 1x,2x and 3x.
You can add more by clicking on tick sign and give sizes like above we give for the iPhones.
Designer will give you proper sizes with respect to resolution to each ipad and iphone
Well it depends on what kind of image you want to display
If it's a solid or pattern image that won't have any different if scaling up / down then I suggest that you put it in image xcassets and use for all supported devices. You should put the largest size image, you can find all screensizes from this: http://iosres.com/
Otherwise, if it's a picture with details like a portrait or food dish, etc. You have to drop it manually with some photo editors like photoshop then add it to xcassets separately for iPhone and iPad
In place of 1x,2x & 3x images take single PDF image and place in image assets it ll fit for all comparability devices.
I think this code will help:
var backGroundImageView :UIImageView! //declare
///set image contentMode in viewDidLoad()
self.backGroundImageView.contentMode = .scaleToFill
However, you should check whether the image is in landscape or portrait orientation.
Image xcassets on #1x,#2x,#3x size will match iPhone 4S screen size automatically, #2x is for the iPhone 5, #3x for the Plus.
As for the iPad you can check the Apple Developers documents.

Can we use just one set of image assert for all resolutions in iOS Development

I just want to use one set of image asserts for all iPhones and iPads(Universal), Is it possible to do the same? or what will be the best solution for the making a build lighter.
YES, it is possible ti use one image asserts for all devices. just add new image set
in assert by Right click. And the add images for required devices in created Image set.
you can use Image set but it's name,and images are automatically loaded with different devices.
UPDATED
if you want to titlelogo.png for all device then make new image set in Images.xcassets and name it as AssetTitlelogo. and the add all images in it as in screenshot.
You use image by
[UIImage imageNamed:#"AssetTitlelogo"]; /// use your asset Name
It's load right image for right Device..
Yes, if you use a retina image without the #2x or #3x in the name and your UIImageView is set to ScaleToFill it will automatically scale down your image on non-retina devices. it is easy to test with the simulators to see how the image will look at the different screen resolutions.
the trade off is non retina devices will suffer with more memory usage than is needed for them (and usually the non-retina devices are some what limited in memory already compared to the latest apple products) but if you arent dealing with a lot of images on the screen at once then this shouldnt have an adverse effect

Making iPad app to support retina display

I have made an iPad app and it works cool. Problem is that my client want's to have retina high resolutions also supported in the app. So lets say We are using images with normal resolution in the app are of 15mb , so again we need to add high resolution each file. So it will increase the file. Is there any way where we can just place high res files only and they should work on both retina and non-retina .
You can fetch image asset using [UIImage imageWithName] in that case, at the runtime appropriate image will be fetched for the device, i.e. if you'll use non-retina device it'll take 1x images and if you use retina device it'll use 2x images.
But, if you want you can fetch the file with [UIImage imageWithContentsOfFile:] you'll be able to fetch that particular file.
You can also use ImageOptim tool to optimse the image without image quality loss.

Retina images, non retina devices [duplicate]

This question already has answers here:
Not including non-retina display images in an iPhone project
(3 answers)
Closed 9 years ago.
I have an app that runs on iPhone and iPad, most of the intended devices for this app will be retina devices except for the iPad mini. I have a lot of images to include in this app.
My question is, if I decide to go with the #2x images only, will iOS downgrade them to non retina devices? so I ship only retina images? If that is correct is it a bad idea to implement?
iOS will not downgrade those images. But if you are setting the frames of your imageviews carefully, it will not create any problem.
If your image view have contentMode = scale your images will be scaled to display correctly on non-retina
But there is some problems:
1) if you display scaled retina image on non-retina device you will have blurred edges on image. So if you want to use this images for UI - it will be bad idea.
2) Sometime xCode storyboards does not scale correctly image if you have only #2x image (for example in uibuttons)
If you are assigning the images in Interface Builder, and you set the image property on a UIImageView to image#2x.png, for example, iOS will not know that it's a high resolution "2x" image. In fact, on a retina display, iOS will look for an image named image#2x#2x.png. Since it won't find it, it will set the scale factor of the image to 1.0.
The contentMode property (just "mode" in XCode) will decide if any scaling of the image occurs to fit the constraints of the UIImageView. You may wish to set the mode to "Aspect Fit" to get the high resolution image to scale as needed for both retina and non-retina displays. In general, the image will display as seen in Interface Builder.
If you are using UIImage's imageNamed or similar function to load the image, and just specify image (where "image.png" doesn't exist, but "image#2x.png" does), then iOS will actually find the image on a non-retina display, though the scale factor will be 1.0. As previously, you'll need to scale it to fit your view. The image will work normally on a retina device, and the scale factor will be set to 2.0, since iOS looks for a "2x" image first, and it doesn't matter if the other file exists or not.
This is from Apple's documentation on imageNamed:
On a device running iOS 4 or later, the behavior is identical if the
device’s screen has a scale of 1.0. If the screen has a scale of 2.0,
this method first searches for an image file with the same filename
with an #2x suffix appended to it. For example, if the file’s name is
button, it first searches for button#2x. If it finds a 2x, it loads
that image and sets the scale property of the returned UIImage object
to 2.0. Otherwise, it loads the unmodified filename and sets the scale
property to 1.0. See iOS App Programming Guide for more information on
supporting images with different scale factors.
If at all possible, you really should include both retina and non-retina images. Using higher-resolution images than necessary negatively affects memory and performance.

Resources