i need a little help with iphone rotation in landscape mode the navigation bar is not being stretched
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// Override point for customization after application launch.
UIImage *navBarImage = [UIImage imageNamed:#"nav-bar.png"];
[[UINavigationBar appearance] setBackgroundImage:navBarImage
forBarMetrics:UIBarMetricsDefault];
UIImage *barButton = [[UIImage imageNamed:#"bar-button.png"] resizableImageWithCapInsets:UIEdgeInsetsMake(0, 5, 0, 5)];
[[UIBarButtonItem appearance] setBackgroundImage:barButton forState:UIControlStateNormal
barMetrics:UIBarMetricsDefault];
UIImage *backButton = [[UIImage imageNamed:#"back-button.png"] resizableImageWithCapInsets:UIEdgeInsetsMake(0,15,0,6)];
[[UIBarButtonItem appearance] setBackButtonBackgroundImage:backButton forState:UIControlStateNormal
barMetrics:UIBarMetricsDefault];
return YES;
}
You don't write this code in this method.First of all you have to return Yes in the method -
(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return YES;
}
And then you have to use :
-(void)willRotateToInterfaceOrientation: (UIInterfaceOrientation)orientation
{ if(orientation == UIInterfaceOrientationPortrait)
// here your code
}
Related
I am able to set the background for my navbar to a custom image in the app delegate didFinishLaunchingWithOptions method with this code:
UIImage *navBarImage;
navBarImage = [UIImage imageNamed:#"navbar.png"];
[[UINavigationBar appearance] setBackgroundImage: navBarImage forBarMetrics:UIBarMetricsDefault];
I'm trying to add an option in my app to change the background image of the navbar when a switch is toggled, however it does not seem to work. Is it only possible to set the background image when the app launches? How can I do this after the app has already launched?
This is the code I have:
- (void) switchChanged:(id)sender {
UISwitch* switchView = sender;
if (switchView.isOn) {
UIImage *navBarImage = [UIImage imageNamed:#"black_nav.png"];
[[UINavigationBar appearance] setBackgroundImage: navBarImage forBarMetrics:UIBarMetricsDefault];
}
else {
UIImage *navBarImage = [UIImage imageNamed:#"white_nav.png"];
[[UINavigationBar appearance] setBackgroundImage: navBarImage forBarMetrics:UIBarMetricsDefault];
}
}
Use setBackgroundImage:forBarMetrics: method:
[navbar setBackgroundImage:[UIImage imageNamed:#"navbar"]
forBarMetrics:UIBarMetricsDefault];
You can replace the default in each view doing this:
UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(0,0,
self.navigationController.navigationBar.frame.size.width,
self.navigationController.navigationBar.frame.size.height)];
[imageView setImage:[UIImage imageNamed:#"newImage.png"]];
[self.navigationController.navigationBar addSubview:imageView];
[self.navigationController.navigationBar sendSubviewToBack:imageView];
Try this one
// Create resizable images
UIImage *gradientImage44 = [[UIImage imageNamed:#"surf_gradient_textured_44"]
resizableImageWithCapInsets:UIEdgeInsetsMake(0, 0, 0, 0)];
UIImage *gradientImage32 = [[UIImage imageNamed:#"surf_gradient_textured_32"] resizableImageWithCapInsets:UIEdgeInsetsMake(0, 0, 0, 0)];
// Set the background image for all UINavigationBars
[[UINavigationBar appearance] setBackgroundImage:gradientImage44 forBarMetrics:UIBarMetricsDefault];
[[UINavigationBar appearance] setBackgroundImage:gradientImage32 forBarMetrics:UIBarMetricsLandscapePhone];
I know how to customize UIBarButtonItem using -setBackgroundImage: forState: barMetrics:, but I would like to use different images for UIBarButtonItemStyleDone and UIBarButtonItemStylePlain.
Is there a way to accomplish this using the UIAppearance protocol? Or do I have to set the image each time I want a "Done" style button?
(I tried messing around with code like the following:
[[UIBarButtonItem appearance] setBackgroundImage:image forState:UIControlStateNormal barMetrics:UIBarButtonItemStyleDone];
But that just sets every bar button with the "Done" image.)
Thanks!
In iOS 6 you can use the new method of UIBarButtonItem class:
- (void)setBackgroundImage:(UIImage *)backgroundImage
forState:(UIControlState)state
style:(UIBarButtonItemStyle)style
barMetrics:(UIBarMetrics)barMetrics
It sets the background image for the specified state, style, and metrics.
More details are available in the Apple docs
So to change the appearance of all UIBarButtonItems you can use something like:
UIImage *doneBackgroundImage = [[UIImage imageNamed:#"button_done.png"]
resizableImageWithCapInsets:UIEdgeInsetsMake(0, 4, 0, 4)];
[[UIBarButtonItem appearance] setBackgroundImage:doneBackgroundImage
forState:UIControlStateNormal
style:UIBarButtonItemStyleDone
barMetrics:UIBarMetricsDefault];
for IOS5*
The only way I found is using a UIBarButtonItem category:
UIBarButtonItem+Appearance.h
#import <Foundation/Foundation.h>
#interface UIBarButtonItem (Appearance)
+ (void) setupAppearance;
#end
UIBarButtonItem+Appearance.m
#import "UIBarButtonItem+Appearance.h"
#import <objc/runtime.h>
#implementation UIBarButtonItem (Appearance)
+ (void) setupAppearance {
[[UIBarButtonItem appearance] setBackgroundImage: [[UIImage imageNamed:#"customButton"]
resizableImageWithCapInsets: UIEdgeInsetsMake(8, 8, 8, 8)]
forState: UIControlStateNormal
barMetrics: UIBarMetricsDefault];
[[UIBarButtonItem appearance] setBackgroundImage: [[UIImage imageNamed:#"customButtonHiglhighted"]
resizableImageWithCapInsets: UIEdgeInsetsMake(8, 8, 8, 8)]
forState: UIControlStateHighlighted
barMetrics: UIBarMetricsDefault];
Class klass = objc_getClass("UIBarButtonItem");
Method targetMethod = class_getInstanceMethod(klass, #selector(setStyle:));
Method newMethod = class_getInstanceMethod(klass, #selector(__setStyle:));
method_exchangeImplementations(targetMethod, newMethod);
}
- (void) __setStyle:(UIBarButtonItemStyle)style {
[self __setStyle:style];
if(style == UIBarButtonItemStyleDone) {
[self setBackgroundImage:[[UIImage imageNamed:#"customDoneButton"] resizableImageWithCapInsets: UIEdgeInsetsMake(8, 8, 8, 8)]
forState:UIControlStateNormal barMetrics:UIBarMetricsDefault];
[self setBackgroundImage:[UIImage imageNamed:#"customDoneButtonClicked"]
forState:UIControlStateHighlighted barMetrics:UIBarMetricsDefault];
} else {
[self setBackgroundImage:[[UIImage imageNamed:#"customButton"] resizableImageWithCapInsets: UIEdgeInsetsMake(8, 8, 8, 8)]
forState:UIControlStateNormal barMetrics:UIBarMetricsDefault];
[self setBackgroundImage:[UIImage imageNamed:#"customButtonHighlighted"]
forState:UIControlStateHighlighted barMetrics:UIBarMetricsDefault];
}
}
#end
Hope this is what you are looking for.
Credit for this solution goes to https://gist.github.com/2633081
I'm trying to change the background image of the Navigation Bar buttons for all the app. I guess it has to be done in the appDelegate.
Many thanks
You can use the appearance proxy for that. Just add this in your appDelegate
- (BOOL)application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
//...
UIImage *myImage = [UIImage imageNamed:#"barButtonItemBackground.png"];
[[UIBarButtonItem appearanceWhenContainedIn:[UINavigationBar class], nil] setBackgroundImage:myImage forState:UIControlStateNormal barMetrics:UIBarMetricsDefault];
return YES;
}
For more detail check the session 114 of the WWDC 2011
If your target is iOS 5, you can put this code in your AppDelegate:
float version = [[[UIDevice currentDevice] systemVersion] floatValue];
if (version >= 5.0)
{
// iPhone 5.0 code here
UIImage *image = [UIImage imageNamed: #"image.png"];
[[UIBarButtonItem appearance] setBackButtonBackgroundImage:image forState:UIControlStateNormal barMetrics:UIBarMetricsDefault];
}
I am working on iPhone app. I have added Navigation bar Background image
With interface: -
#interface UINavigationBar (backgroundImageWithTitle)
And method: -
- (void)drawRect:(CGRect)rect
By this method Navigation bar background images is being set one time.
I want to call it from different .m files for assigning different images on bar.
How it can be implemented?
Thanks in advance.
CustomNavigation.h
#import <Foundation/Foundation.h>
#interface UINavigationBar (UINavigationBarCustomDraw){
}
#end
CustomNavigation.m
#implementation UINavigationBar (UINavigationBarCustomDraw)
- (void) drawRect:(CGRect)rect {
[self setTintColor:[UIColor colorWithRed:0.5f
green: 0.5f
blue:0
alpha:1]];
if ([self.topItem.title length] > 0) {
if ([self.topItem.title isEqualToString:#"First"]) {
[[UIImage imageNamed:#"First.png"] drawInRect:rect];
}
else if ([self.topItem.title isEqualToString:#"Second"]) {
[[UIImage imageNamed:#"Second.png"] drawInRect:rect];
}
CGRect frame = CGRectMake(0, 0, 320, 44);
UILabel *label = [[[UILabel alloc] initWithFrame:frame] autorelease];
[label setBackgroundColor:[UIColor clearColor]];
label.font = [UIFont boldSystemFontOfSize: 20.0];
label.shadowColor = [UIColor colorWithWhite:0.0 alpha:1];
label.textAlignment = UITextAlignmentCenter;
label.textColor = [UIColor whiteColor];
label.text = self.topItem.title;
self.topItem.titleView = label;
}
else {
[[UIImage imageNamed:#"wood.png"] drawInRect:rect];
self.topItem.titleView = [[[UIView alloc] init] autorelease];
}
}
#end
if u want to First.png to set navigationBar background image in FirstViewController then
in ur FirstViewController.m
-(void) viewWillAppear:(BOOL)animated{
[super viewWillAppear:animated];
self.title=#"First";
[self.navigationController.navigationBar drawRect:CGRectMake(0, 0, 320, 480)];
}
if u want to Second.png to set navigationBar background image in SecondViewController then
in ur SecondViewController.m
-(void) viewWillAppear:(BOOL)animated{
[super viewWillAppear:animated];
self.title=#"Second";
[self.navigationController.navigationBar drawRect:CGRectMake(0, 0, 320, 480)];
}
On iOS 5 this will not work but the good news is that there is a simple way of doing this
[[UINavigationBar appearance] setBackgroundImage:[UIImage imageNamed:#"name"] forBarMetrics:UIBarMetricsDefault];
NOTE: This will only work on iOS 5 and above so make sure you check iOS version if you want to be backwards compatible.
Or other option so that code runs only incase of iOS 5
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];
}
I have tried this
[[UINavigationBar appearance] setBackgroundImage:[UIImage imageNamed:#"name"] forBarMetrics:UIBarMetricsDefault];
It works fine for iOS 5.0 but got crashed in iOS 4.3 or below.
You have either set conditional i.e for
iOS 5
[[UINavigationBar appearance] setBackgroundImage:[UIImage imageNamed:#"name"] forBarMetrics:UIBarMetricsDefault];
else
[[UINavigationBar appearance] setBackgroundImage:[UIImage imageNamed:#"name"]];
but still there is issue that it shows line under image.
Or you can do in this way
self.navigationItem.hidesBackButton = YES;
UINavigationBar *navBar = self.navigationController.navigationBar;
UIImage *image = [UIImage imageNamed:#"image.png"];
UIView *tempView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 45)];
UIImageView *imgView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 320, 45)];
imgView.image = image;
[tempView addSubview:imgView];
[navBar clearBackgroundImage];
[navBar addSubview:tempView];
[tempView release];
You can try in this way
if([[UINavigationBar class] respondsToSelector:#selector(appearance)]) //iOS >=5.0
{
//[[UINavigationBar appearance] setFrame:CGRectMake(0, 0, 320, 40)];
[[UINavigationBar appearance] setBackgroundImage:[UIImage imageNamed:#"navigationBar.png"] forBarMetrics:UIBarMetricsDefault];
[[UINavigationBar appearance] setBackgroundImage:[UIImage imageNamed:#"navBar-Landscape.png"] forBarMetrics:UIBarMetricsLandscapePhone];
[[UINavigationBar appearance] setBarStyle:UIBarStyleBlack];
}
and in else case you can add previous code i.e setBackgroundImage ....
Using (SDK 3.2.5.) - In one of my Apps I needed navigationBar with custom image both in landscape and portrait.
What I did was:
#implementation UINavigationBar (BackgroundImage)
- (void)drawRect:(CGRect)rect
{
UIImage *image;
if(self.frame.size.width == 320) //for iPhone - portrait will have 320 pix width.
{
image = [UIImage imageNamed: #"portraitNavigationBar.png"];
}
else
{
image = [UIImage imageNamed: #"landscapeNavigationBar.png"];
}
[image drawInRect:CGRectMake(0, 0, self.frame.size.width, self.frame.size.height)];
}
#end
Luckily my app supports rotation - so, when rotating - navigation bar automatically redraws itself.
But to manually redraw it - you can also call :
[navigationController.navigationBar setNeedsDisplay];
I have an application with 4 tabs. Each tab is a UINavigationController. The 4 UINavigationBar tabs should look the same, have a custom background image, a custom backButton and a custom right button triggering a function.
I would like to do those customizations only once in my code and not in each RootViewController.
I managed to have a custom background image by inserting this code into my appDelegate:
#implementation UINavigationBar (CustomImage)
- (void)drawRect:(CGRect)rect {
UIImage *image = [UIImage imageNamed: #"MyNavigationBar.png"];
[image drawInRect:CGRectMake(0, 0, self.frame.size.width, self.frame.size.height)];
}
#end
But I didn't manage to customize the back and right buttons or specify the action for the right button.
Is there a way to do that in the appDelegate, just like for the background image?
Or should I do the customization in each RootViewController?
Write the below code in viewWillAppear method
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
UIImage *butImage = [[UIImage imageNamed:#"back.png"] stretchableImageWithLeftCapWidth:10 topCapHeight:10];
[button setBackgroundImage:butImage forState:UIControlStateNormal];
[button addTarget:self action:#selector(gotoBack:) forControlEvents:UIControlEventTouchUpInside];
button.frame = CGRectMake(0, 0, 48, 30);
UIBarButtonItem *backButton = [[[UIBarButtonItem alloc] initWithCustomView:button] autorelease];
self.navigationItem.leftBarButtonItem = backButton;
and write the action event for backButton.
-(IBAction)gotoBack:(id)sender
{
[self.navigationController popViewControllerAnimated:YES];
}
In your appdelegate in aplicationDidFinishLaunching.....
UIImage *navBG = [UIImage imageNamed:#"barra-logo-centro.png"];
[[UINavigationBar appearance] setBackgroundImage:navBG forBarMetrics:UIBarMetricsDefault];
//backbutton: 22x30 , 44x60#2x
[[UIBarButtonItem appearance] setBackButtonBackgroundImage:[UIImage imageNamed:#"back_button.png"] forState:UIControlStateNormal barMetrics:UIBarMetricsDefault];
[[UIBarButtonItem appearance] setBackgroundImage:[UIImage imageNamed:#"normal_button.png"] forState:UIControlStateNormal barMetrics:UIBarMetricsDefault];
this will modify the complete proyect navigationbar and bar button ítems
Renungas answer works fine.
If you don't want to write the same code 4 times you can
always subclass UINavigationController.
I just tried this solution (with subclassing UITabBarController but nevertheless...)
and it works ok.
You can find similiar example here
Your custom code (identical to the mentioned example) should look like this:
- (void)loadView {
[super loadView];
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
[button setImage:[UIImage imageNamed:#"backbutton.png"] forState:UIControlStateNormal];
[button addTarget:self action:#selector(backAction) forControlEvents:UIControlEventTouchUpInside];
[button setFrame:CGRectMake(0, 0, 32, 32)];
self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:button];
}
- (void)backAction {
[self.navigationController popViewControllerAnimated:YES];
}
As you can see all you have to do is override loadView and add a method
to perform the popVievController selector.
Good luck!