I am trying to customize UI appearance of my app. I used following code, whcih works fine on non iPhone5 and successors (and non retina display), It appears great on simulator.
but on my iPhone5 its not loading the images.
-(void)customizeAppearance
{
UIImage* blueBG = [UIImage imageNamed:#"menubar.png"];
[[UINavigationBar appearance] setBackgroundImage:blueBG forBarMetrics:UIBarMetricsDefault];
UIImage* blueBack = [UIImage imageNamed:#"back.png"];
[[UIBarButtonItem appearance] setBackButtonBackgroundImage:blueBack forState:UIControlStateNormal barMetrics:UIBarMetricsDefault];
UIImage* blueTabBG = [UIImage imageNamed:#"tabbar-active.png"];
[[UITabBar appearance] setBackgroundImage:blueTabBG];
How can I make this conditional load of resource like
if(___IPHONE5ORLATER)
load retina images
else
load non retina images
You don't have to use this type of condition for load retina images,
Put two images
menubar.png (non retina) (e.g 30 X 30 px)
menubar#2x.png (retina image) (e.g 60 X 60 px)
Now you simple use
UIImage* blueBG = [UIImage imageNamed:#"menubar"];
iOS will automatically load retina image if device is retina.
Related
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];
I'm trying to center a background UIImage in a UINavigationController that's instantiated in code:
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:mainMenuViewController];
self.window.rootViewController = navController;
UIImage *navBackgroundImage = [UIImage imageNamed:#"fancy_header_logo"];
navBackgroundImage = [navBackgroundImage imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
[[UINavigationBar appearance] setBackgroundImage:navBackgroundImage forBarMetrics:UIBarMetricsDefault];
[[UINavigationBar appearance] setBarStyle:UIBarStyleBlack];
[navController.navigationBar setContentMode:UIViewContentModeCenter];
navController.navigationBar.autoresizingMask = UIViewAutoresizingFlexibleTopMargin;
The image displays correctly in portrait on all devices except for the iPhone 6. The image is stored in Images.xcassets in 1x, 2x, Retina 4 2x, 3x, and iPad 2x sizes.
Any pointers or suggestions would be greatly appreciated. Many thanks in advance.
UPDATE:
I've made some progress. Taking a hint from this answer I made some changes:
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:mainMenuViewController];
self.window.rootViewController = navController;
UIImage *navBackgroundImage = [[UIImage imageNamed:#"fancy_header_logo"] resizableImageWithCapInsets:UIEdgeInsetsMake(0, -260, 0, 0)];
[[UINavigationBar appearance] setBackgroundImage:navBackgroundImage forBarMetrics:UIBarMetricsDefault];
[[UINavigationBar appearance] setBarStyle:UIBarStyleBlack];
This now works in all cases except iPhone 6 (not plus) in portrait (the app does not rotate on iPhones.) Now the image is scaled larger and instead of being left justified, it is now scaled larger and is too far to the right.
For the record, the image is being used when stepping through the code running in the iPhone simulator is 640x128 at 144 ppi.
UPDATE 2:
It appears that the iPhone 6 is using the image listed as 2x (in the .xcassets file) This is the same file as used by the iPhone 4 (in the simulator.) I have tried massaging the png file so that it displays right on the iPhone 6, but makes it display incorrectly on the iPhone 4.
Im not sure if this is the correct answer or not but I discovered that it doesn't seem to natively show as an iPhone 6 and 6 plus application unless your app has a launch image for the bigger iPhones.
Try just adding a launch image for these devices :)
Check this:
UIImage *image = [UIImage imageNamed: #"logo"];
UIImageView *imageView = [[UIImageView alloc] initWithImage: image];
self.navigationItem.titleView = imageView;
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"];
I display a retina image (with #2x.png extension) using:
myImage = [UIImage imageNamed:#"iPhoneBackground#2x.jpg"];
UIGraphicsBeginImageContext(myImage.size);
[myImage drawAtPoint: CGPointZero];
myImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
imageView = [[UIImageView alloc] initWithImage:myImage];
NSLog(#"Dimension:%f x %f",myImage.size.width,myImage.size.height);
[self.view addSubview:imageView];
However the image is displayed twice its size on the retina simulation. Image and simulator both have 640 x 960 resolution, so I would expect the image filling the screen.
I know there are other ways than CGContext to display an image, but that's the way I would need to other purposes in my code.
Any idea why I have this definition issue ?
Don't use #2x suffix
From apple documentation:
The UIImage class handles all of the work needed to load
high-resolution images into your app. When creating new image objects,
you use the same name to request both the standard and the
high-resolution versions of your image. For example, if you have two
image files, named Button.png and Button#2x.png, you would use the
following code to request your button image:
UIImage *anImage = [UIImage imageNamed:#"Button"];
You do not need to explicitly load a retina image, #2x will be automatically appended to the image name if the device has a retina display.
Change your UIImage code to: myImage = [UIImage imageNamed:#"iPhoneBackground.jpg"];
is there a way to use a different images for the ipad landscape/portrait mode? My navigationbar contains a logo in the middle and while it works great on the iphone with different images, I can't use different images for the iPad so the logo isn't centered when you turn the device.
Alternatively, I can use a plain background image and maybe replace the navigation bar title with an image or center a button but I also couldn't manage to do that either. (I don't have a UINavigationController subclass).
here is my code that is doing the trick so far inside the app delegate:
if ([UINavigationBar respondsToSelector:#selector(appearance)]) {
// Create resizable images for iphone
UIImage *navbarImage44 = [[UIImage imageNamed:#"nav_bar"]
resizableImageWithCapInsets:UIEdgeInsetsMake(0, 0, 0, 0)];
UIImage *navbarImage32 = [[UIImage imageNamed:#"nav_bar_landscape"]
resizableImageWithCapInsets:UIEdgeInsetsMake(0, 0, 0, 0)];
// Overide for iPad
// In theory navbar_bg_landscape~iPad should work
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
//use iPad specific image extending last pixel for landscape mode
[[UINavigationBar appearance] setBackgroundImage:[[UIImage imageNamed:#"nav_bar_ipad" ]
resizableImageWithCapInsets:UIEdgeInsetsMake(0, 0, 0, 0)]
forBarMetrics:UIBarMetricsDefault];
}else {
// Set the background image for *all* UINavigationBars
[[UINavigationBar appearance] setBackgroundImage:navbarImage44
forBarMetrics:UIBarMetricsDefault];
// Never called on iPad, used for landscape on iPhone
[[UINavigationBar appearance] setBackgroundImage:navbarImage32
forBarMetrics:UIBarMetricsLandscapePhone];
}
}
I didn't get any response on this so I found a work around which is to resize the image on landscape. I'm ok with that for now. I'm resizing my portrait background image - here is my code for iPad
// Create resizable images
UIImage *ipadTabBarBG = [[UIImage imageNamed:#"nav_bar_ipad.png"]
resizableImageWithCapInsets:UIEdgeInsetsMake(0, -260, 0, 0)];
// Set the background image for *all* UINavigationBars
[[UINavigationBar appearance] setBackgroundImage:ipadTabBarBG
forBarMetrics:UIBarMetricsDefault];