I'm developing Tab bar Application and found strange issue on iPhone 6
Notice that image is not wide enough for full screen but repeated.
I have set image through both storyboard and programmatically
I have also have 2x and 3x images placed in Images.xcassets
For any one who comes here later, here is what i do
After Some tries i've used a hack as follow
Do not used images from assets instead place them as files (we do before assets)
Check if we have iPhone 6 and user #3x image, (i was not sure why it was not picked by assets but it do in this manner)
Following is code
#define isIPhone6 [[UIScreen mainScreen] bounds].size.height > 568 ? YES : NO
UITabBar *tabBar = tabBarController.tabBar;
UIImage* tabBarBackground = [UIImage imageNamed:#"tab_bar1.png"];
if (isIPhone6) {
tabBarBackground = [UIImage imageNamed:#"tab_bar2#3x.png"];
}
[tabBar setBackgroundImage:tabBarBackground];
Related
I have created a UITabBarcontroller programatically as follows:
UITabBarController *tbc = [[UITabBarController alloc] init];
[tbc setViewControllers:[NSArray arrayWithObjects:vc1,vc2,vc3,vc4,vc5,nil]];
which works ok. For each of the UIViewControllers, i want to set their tabbaritem.image to a specified image so i do this:
UITabBarItem *tbi1 = [[UITabBarItem alloc] initWithTitle:#"Search" image:
[UIImage imageNamed:#"tab_bar_search_50_50.png"] tag:0];
vc1.tabBarItem = tbi1;
and i have also tried
vc1.tabBarItem.image = [UIImage imageNamed:#"tab_bar_search_50_50.png"];
and
UITabBarItem *tbi1 = [[UITabBarItem alloc] initWithTitle:#"Search" image:
[UIImage imageNamed:#"tab_bar_search_50_50.png"] selectedImage:
[UIImage imageNamed:#"tab_bar_search_50_50.png"]];
The image size is 50x50 because according to apple-> https://developer.apple.com/library/ios/documentation/UserExperience/Conceptual/MobileHIG/IconMatrix.html#//apple_ref/doc/uid/TP40006556-CH27-SW1
a tabbar icon of size "About 50 x 50 (maximum: 96 x 64) is ok". Yet when i run this in both the simulator and on a device (both retina screens) the image is way too large and hangs over the top of the the tab bar.
Ive even tried adding #2x as a suffix to the file name which doesnt work, but i thought since the app is building only for ios7 that these were no longer needed?
Im guessing the problem is either a bug in iOS7 or the issue lies with the image size, but i read in the documentation that if the image is too big it will be clipped to a certain bound?
I believe i have solved my problem. The problem was that when i added the #2x suffix, i also included this in the naming of the UIImage:
[UIImage imageNamed #"image#2x.png"];
But this needs to be:
[UIImage imageNamed #"image.png"];
So I need to differentiate the screen size (3.4 or 4 inch) devices in order to select the right image to display.
Here is what I did: -- from here
#define IS_PHONEPOD5() ([UIScreen mainScreen].bounds.size.height == 568.0f && [UIScreen mainScreen].scale == 2.f && UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone)
if(IS_PHONEPOD5()) {
self.tutorialImageView.image = [UIImage imageNamed:#"tutorialOverlay-568h#2x.png"];
} else {
self.tutorialImageView.image = [UIImage imageNamed:#"tutorialOverlay.png"];
}
Regardless of the screen size the image view always contains the larger image and extends off the screen (on the 3.5")
Am I doing something wrong, I have tried a few other things and it has always done the same thing.
EDIT: Even if I don't ever select the larger image it still is the one on screen at runtime:
self.tutorialImageView.image = [UIImage imageNamed:#"tutorialOverlay.png"];
It is still the larger image?
Have you checked UIViewContentMode of UIImageView? Try it by setting UIViewContentModeScaleAspectFit and check if it works.
don't use #2x in your image string. because every retina device will automatically take care of that.
use should save your image text like image#2x.png but i must use only without #2x extention. use properly like [UIImage imageNamed:#"image.png"]; this is for 3.5 inch.
How to use 4 inch screen use extention with -568h. Eg:
image-568h#2x.png. use like [UIImage imageNamed:#"image-568h.png"];
self.tutorialImageView.image = [UIImage imageNamed:#"tutorialOverlay-568h.png"];
more detail
https://developer.apple.com/library/ios/documentation/iphone/conceptual/iphoneosprogrammingguide/App-RelatedResources/App-RelatedResources.html
Edited:
self.navigationcontroller.navigationbar.translucent = NO;
In a universal app should I have a image.png, image#2x.png, image~ipad.png and image#2x~ipad.png for every image in my project?
Or should I just use my wider iPad images and have iOS scale them down to iPhone for me?
There's a lot of images so I'm a bit concerned about the file size...
Thanks!
Not necessarily but you can see code below. If you are targeting low res iPads and Low res iPhones you would have one set of icons for each. So if you are targeting iPad retina and iPhone retina that is on set of icons too so if you have an image called car.png and car#2x.png you would have 2 icons that cover all 4 models mentioned.
You can of course have images specific for iPad as the screen is larger then in your logic you would show either or depending on the device idiom..like below
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) {
//Device is iPhone
//This would give you low res icon for iPhone and if device is retina system will show it
UIImage *car = [UIImage imageNamed: #"Car.png"];
UIImageView *carImage = [[UIImageView alloc]initWithImage:car];
}
else {
//Device is iPad
//This would give you low res icon for iPad and if device is retina system will show it
UIImage *carLarge = [UIImage imageNamed: #"CarLarge.png"];
UIImageView *carImage = [[UIImageView alloc]initWithImage:carLarge];
}
I have in my viewController.m written the background code:
self.view.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:#"image.png"]];
And I have the correct names of the different pictures:
image.png for non-retina display (320x480)
image#2x.png for retina display (640x960)
image-568h#2x.png for iPhone 5 (640x1136)
But when I run it in the simulator it does not take the image-568h#2x.png for iPhone 5 screen it only takes the image#2x for 4s screen and scale it to fit the screen... I dont know if there is any coding to use the image-568h#2x for iPhone 5 screen?
Im using Xcode 4.5
iPhone 5 is retina, just like iPhone 4 and 4S, and the #2x-image will be used automatically for all these devices. It's only the startup-image that is called "-568h#2x" for iPhone 5. You need to write some code to use a different image, something like this would work:
NSString *filename = #"image.png";
CGRect screenRect = [[UIScreen mainScreen] bounds];
if (screenRect.size.height == 568.0f)
filename = [filename stringByReplacingOccurrencesOfString:#".png" withString:#"-568h.png"];
imageView.image = [UIImage imageNamed:filename];
if you are trying to use [UIImage imageNamed:#"image.png"] and expect image-568h#2x.png to be picked automatically from the bundle for iPhone 5, it will not work.
Automatic picking works only for iPhone 4 and 4S.
Only the Default image named as Default-568h#2x.png will be picked automatically in iPhone 5.
for normal images, if you have separate image for iPhone 5, try using this code
CGRect screenBounds = [[UIScreen mainScreen] bounds];
if (screenBounds.size.height == 568) {
// code for 4-inch screen
} else {
// code for 3.5-inch screen
}
I believe it is incorrect to assume that you can apply the -568h#2x trick to all image files. I think it only works for Default-568h#2x.png. This is the file that iOS looks for at app launch on a 4" display device, as well as the "flag" to enable 4" display support in the SDK. For example, once you include this specific file, your table views will fill the screen.
I have not read anything to suggest that you can simply provide any image with the -568h#2x file name component and have it be used automagically. You'll have to do that yourself based on the screen size, e.g. [UIScreen mainScreen].bounds.size.height.
I am on my voyage to supporting the iPhone 5. I am well aware that there is iOS 6's auto layout feature in Interface Builder. This is great however, sometimes I want to load my own images if its an iPhone 5.
So some of the images in my game for iPhones are exactly the screen's size either (320x480) or (640 x 960). So if I am on an iPhone 5 those images will not cover the entire screen. So I am going to make (640 x 1136) images for those full screen images.
Now I know that if I simply name the image: MyImage-568h#2x.png it won't load. So, how would I subclass UIImage so that it will load the -568h#2x image thats not the default image?
Thanks!
The lazy way:
UIImage * img = [UIScreen mainScreen].bounds.size.height > 500 ? [UIImage imageNamed:#"Default-568h.png"] : [UIImage imageNamed:#"Default.png"];
I've done this in an app where the main screen on devices without a camera is Default.png; it doesn't seem too hacky because we would need to change Default.png to support new devices anyway.
The less lazy way: Condition on the space you need to fill, not the screen size.
The solution you asked for isn't really generic enough to warrant a class, but here it is anyway:
#implementation MyImage
+(UIImage)imageNamed:(NSString*)name {
if ([UIScreen mainScreen].bounds.size.height > 500) {
UIImage * img = [UIImage imageNamed:[name stringByAppendingString:#"-iPhone5"];
if (img) { return img; }
}
return [UIImage imageNamed:name];
}
#end
There's really no need to subclass UIImage. If you're feeling really hacky, you can patch/swizzle/otherwise +[UIImage imageNamed:] to point to a custom method, but I really don't recommend that except for debugging.