change background image of navigation bar based on orientation - objective-c

Is there a way to change the background image of navigation bar based on orientation? I tried using methods in the app delegate such as :
-(void)application:(UIApplication *)application didChangeStatusBarFrame:(CGRect)oldStatusBarFrame
{
UIInterfaceOrientation orientation = [UIApplication sharedApplication].statusBarOrientation;
if(orientation == (UIInterfaceOrientationMaskPortrait)||orientation==(UIInterfaceOrientationMaskPortraitUpsideDown)){
UIImage *myImage = [UIImage imageNamed:#"borderP.png"];
UIImage * imageBottom = [UIImage imageNamed:#"bottomP.png"];
[[UIToolbar appearance] setBackgroundImage:imageBottom forToolbarPosition:UIToolbarPositionAny barMetrics:UIBarMetricsDefault];
[[UINavigationBar appearance] setBackgroundImage:myImage forBarMetrics:UIBarMetricsDefault];
[[UIToolbar appearance] setBackgroundImage:imageBottom forToolbarPosition:UIToolbarPositionAny barMetrics:UIBarMetricsDefault];
NSLog(#"******P******");
}
else if(orientation == (UIInterfaceOrientationMaskLandscapeLeft||orientation== UIInterfaceOrientationMaskLandscapeRight)){
UIImage *myImage = [UIImage imageNamed:#"borderL.png"];
UIImage * imageBottom = [UIImage imageNamed:#"borderL.png"];
[[UIToolbar appearance] setBackgroundImage:imageBottom forToolbarPosition:UIToolbarPositionAny barMetrics:UIBarMetricsDefault];
[[UINavigationBar appearance] setBackgroundImage:myImage forBarMetrics:UIBarMetricsDefault];
[[UIToolbar appearance] setBackgroundImage:imageBottom forToolbarPosition:UIToolbarPositionAny barMetrics:UIBarMetricsDefault];
NSLog(#"******L********");
}
}
but the back ground image does not change.
Any advice?

The appearance proxy only applies only to new instances. To modify an instance that already exists, you you need to call setBackgroundImage:forToolbarPosition:barMetrics: on it directly.

Related

Subclass UINavigationbar for customise in iOS7 does not work

I have made a subclass of the navigation bar.
In there I set a background image and I would like to disable the clipping, because my Image has some shadow and an arrow which is higher than the navigation bar.
in iOS 6&5 it works perfectly when I remove the tick Clip Subviews in the Interface Builder in Xcode.
In iOS7 unfortunately the background image is always clipped...
I also tried to add the following lines:
- (void) awakeFromNib
{
// Initialization code
UIImage *image = [UIImage imageNamed:#"tt_navigation_bar.png"];
if ([[UIDevice currentDevice].systemVersion floatValue] >= 7.0) image = [UIImage imageNamed:#"tt_navigation_bar-ios7.png"];
[[UINavigationBar appearance] setBackgroundImage:image forBarMetrics:UIBarMetricsDefault];
NSDictionary *textTitleOptions = [NSDictionary dictionaryWithObjectsAndKeys:[UIFont fontWithName:#"HelveticaNeue-Bold" size:21.0], UITextAttributeFont, [UIColor colorWithRed:255.0/255.0 green:109.0/255.0 blue:36.0/255.0 alpha:1], UITextAttributeTextColor, [UIColor clearColor], UITextAttributeTextShadowColor, nil];
[[UINavigationBar appearance] setTitleTextAttributes:textTitleOptions];
for (UIView *v in [self subviews]) {
NSLog(#"v: %#", v);
v.layer.masksToBounds = NO;
}
self.layer.masksToBounds = NO;
}
I solved this by manually editing my two images into the top n pixels and then "the rest" and setting the image of "the rest" to the shadowImage.

Appearance proxy affected by upgrade to iOS 6

My app implements a custom segmented control background image using:
// customise the segmented controls
UIImage *segmentSelected = [[UIImage imageNamed:#"segcontrol_sel.png"] resizableImageWithCapInsets:UIEdgeInsetsMake(0, 15, 0, 15)];
UIImage *segmentUnselected = [[UIImage imageNamed:#"segcontrol_uns.png"] resizableImageWithCapInsets:UIEdgeInsetsMake(0, 15, 0, 15)];
UIImage *segmentSelectedUnselected = [UIImage imageNamed:#"segcontrol_sel-uns.png"];
UIImage *segUnselectedSelected = [UIImage imageNamed:#"segcontrol_uns-sel.png"];
UIImage *segmentUnselectedUnselected = [UIImage imageNamed:#"segcontrol_uns-uns.png"];
[[UISegmentedControl appearance] setBackgroundImage:segmentUnselected forState:UIControlStateNormal barMetrics:UIBarMetricsDefault];
[[UISegmentedControl appearance] setBackgroundImage:segmentUnselected forState:UIControlStateDisabled barMetrics:UIBarMetricsDefault];
[[UISegmentedControl appearance] setBackgroundImage:segmentSelected forState:UIControlStateSelected barMetrics:UIBarMetricsDefault];
[[UISegmentedControl appearance] setDividerImage:segmentUnselectedUnselected forLeftSegmentState:UIControlStateNormal rightSegmentState:UIControlStateNormal barMetrics:UIBarMetricsDefault];
[[UISegmentedControl appearance] setDividerImage:segmentSelectedUnselected forLeftSegmentState:UIControlStateSelected rightSegmentState:UIControlStateNormal barMetrics:UIBarMetricsDefault];
[[UISegmentedControl appearance] setDividerImage:segUnselectedSelected forLeftSegmentState:UIControlStateNormal rightSegmentState:UIControlStateSelected barMetrics:UIBarMetricsDefault];
It was perfectly working before I updated to XCode 4.5 and iOS6. Now it's like that:
as you can see the background images size were altered. Did any anybody have the same problem?
Also some of the background images for some screen look shorter the requested. In one of them for example I have a blank space.
Make sure you name your images with #2x if they're at that resolution.
I had a similar-looking problem which was fixed when I added that.

How to remove navigation bar's shadow

I have UINavigationBar.
UINavigationBar *navBar = [[UINavigationBar alloc] initWithFrame:CGRectMake(0.0f, 46.0f, 320.0f, 50.0f)];
navBar.tintColor = [UIColor blackColor];
[self.view addSubview:navBar];
And I want to remove standart top shadow. How can I do this?
You can define a custom image for the navbar in iOS 5.0 and above:
UIImage *backgroundImage = [UIImage imageNamed:#"bevel_nav_bar.png"];
[navBar setBackgroundImage:backgroundImage forBarMetrics:UIBarMetricsDefault];

UINavigation bar button background image size

I'm trying sot set image background for the left back button navigation bar for all the app with this snippet:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
float version = [[[UIDevice currentDevice] systemVersion] floatValue];
if (version >= 5.0)
{
// iPhone 5.0 code here
UIImage *image = [UIImage imageNamed: #"btn_back.png"];
image = [image stretchableImageWithLeftCapWidth:40.0f topCapHeight:0.0f];
[[UIBarButtonItem appearance] setBackButtonBackgroundImage:image forState:UIControlStateNormal barMetrics:UIBarMetricsDefault];
}
return YES;
}
I've been trying different values in stretchableImageWithLeftCapWidth: but best result was this:
How can I set background image to the correct size?
Thanks
stretchableImageWithLeftCapWidth:topCapHeight: is deprecated. Use resizableImageWithCapInsets: instead.
This should work:
UIImage *buttonImage = [[UIImage imageNamed:#"btn_back.png"] resizableImageWithCapInsets:UIEdgeInsetsMake(1, 10, 1, 10)];
[[UIBarButtonItem appearance] setBackButtonBackgroundImage:buttonImage forState:UIControlStateNormal barMetrics:UIBarMetricsDefault];

UINavigationBar setBackgroundImage: forBarMetrics: Not Working

I just switched over to iOS 5 and everything appears to be working in my application aside from the custom navigation bar. I looked around and followed everybody's suggestion of calling the new methods setBackgroundImage: forBarMetrics: however it doesn't appear to work. This is the code I've tried to place both within the app delegate and within the viewDidLoad method of some of the view controllers:
UINavigationBar *nb = [[UINavigationBar alloc]init];
if( [nb respondsToSelector:#selector(setBackgroundImage:forBarMetrics:)] )
{
UIImage *image = [UIImage imageNamed:#"navBarBackground.png"];
[nb setBackgroundImage:image forBarMetrics:UIBarMetricsDefault];
}
[nb release];
Unfortunately this doesn't work. If anybody has any suggestions at all, I'm all ears!
To apply image to all your navigation bars, use the appearance proxy:
[[UINavigationBar appearance] setBackgroundImage:image forBarMetrics:UIBarMetricsDefault];
For an individual bar:
// Assuming "self" is a view controller pushed on to a UINavigationController stack
[self.navigationController.navigationBar setBackgroundImage:image forBarMetrics:UIBarMetricsDefault];
In your example, the background image won't change because nb isn't hooked up to anything.
Answer by rob is correct but if application runs on iOS 4.3 or lower app will crash. So you can implement this like
if([[UINavigationBar class] respondsToSelector:#selector(appearance)]) //iOS >=5.0
{
[[UINavigationBar appearance] setBackgroundImage:[UIImage imageNamed:#"navigationBar.png"] forBarMetrics:UIBarMetricsDefault];
[[UINavigationBar appearance] setBackgroundImage:[UIImage imageNamed:#"navBar-Landscape.png"] forBarMetrics:UIBarMetricsLandscapePhone];
}
This will set image for both mode Landscape and Portrait
You need to get the navigation bar from a navigation controller. Right now you are just creating one and then it deallocs when you release it. You need to get the navigation controller for your view controller.
UINavigationController * navigationController = [self navigationController];
UINavigationBar * nb = [navigationController navigationBar];
Note that if you want to apply the same to a toolbar, it is slightly different. Here's an example, building on Rob's answer:
[[UIToolbar appearance] setBackgroundImage:[UIImage imageNamed:#"NavBarDarkWoodGrain.png"] forToolbarPosition:UIToolbarPositionBottom barMetrics:UIBarMetricsDefault];
You didn't do something like use a UINavigationBar subclass? If you do this and override drawRect: on iOS5 and above, things will break.
See my answer here for a way to support both OS versions.
This worked for me.
UIView *parentViewLeft = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 44)];
parentViewLeft.backgroundColor = [UIColor clearColor];
if ([self.navigationController.navigationBar respondsToSelector:#selector(setBackgroundImage:forBarMetrics:)]) {
[self.navigationController.navigationBar setBackgroundImage:[UIImage imageNamed:#"navbar.png"]
forBarMetrics:UIBarMetricsDefault];
} else {
UIImageView* imgBG = [[UIImageView alloc]init];
imgBG.image = [UIImage imageNamed:#"navbar.png"];
imgBG.frame = CGRectMake(-10,0, 330, 44);
[parentViewLeft addSubview:imgBG];
}
UIBarButtonItem *customBarButtomLeft = [[UIBarButtonItem alloc] initWithCustomView:parentViewLeft];
self.navigationItem.leftBarButtonItem = customBarButtomLeft;