Set titleview for all navigationcontroller and navigationitem - iphone

[[[UINavigationBar appearance] setTitleView:button]
I tried to set title view as button for all navigation item using above line of code but it is not working.How can I set title view for all navigation bars in my project by writing small code in appdelegate ?

Customizing the Appearance of a Navigation Bar
it is alright to modify the barStyle, tintColor, and translucent
properties, but you must never directly change UIView-level properties
such as the frame, bounds, alpha, or hidden properties directly.
For more detail you can follow apple doc UINavigationBar Class Reference
Edit ->
I solved your query
[[UINavigationBar appearance] addSubview:yourView];
Other Navigation Related query

try this dude...
//put whatever object in this view..for example button that you want to put...
UIView* ctrl = [[UIView alloc] initWithFrame:navController.navigationBar.bounds];
ctrl.backgroundColor = [UIColor yellowColor];
ctrl.autoresizingMask = UIViewAutoresizingFlexibleWidth;
[navController.navigationBar addSubview:ctrl];
let me know it is working or not!!!!
Happy Coding!!!

This is how you create a navigation controller in addDelegate and set a title to it,
you have to add the following code to didFinishLaunchingWithOptions method.
Notice that you need to set a root view for the viewController which will the viewController that will be displayed inside the navigationController.
yourViewController *mainVC = [[yourViewController alloc]init];
UINavigationController *navigationController1 = [[UINavigationController alloc] initWithRootViewController:mainVC];
navigationController1.title = #"title";
[window addSubview:navigationController1.view];

If you use iOS4, you can override drawRect
#implementation UINavigationBar (UINavigationBarCategory)
-(void)drawRect:(CGRect)rect
{
UIImageView *itleImageView = //create object
[self addSubView:titleImageView];
//set title view in navigation bar
}
#end
iOS 5,
if ([[UIDevice currentDevice].systemVersion floatValue] >= 5.0) {
if ([self.navigationController.navigationBar respondsToSelector:#selector( setBackgroundImage:forBarMetrics:)]){
UIImageView *itleImageView = //create object
[self.navigationController.navigationBar addSubView:titleImageView];
}
}
i guess this is a right, as i don't have implemented.

I wanted to add a logo in every NavigationController, so I made a subclass of
UINavigationController and used this in the viewDidLoad-Method
UIImage *logo =[UIImage imageNamed:#"logo"];
CGFloat navWidth = self.navigationBar.frame.size.width;
CGFloat navHeight = self.navigationBar.frame.size.height;
UIImageView *logoView = [[UIImageView alloc] initWithFrame:CGRectMake(navWidth-logo.size.width - 5,
(navHeight - logo.size.height) / 2,
logo.size.width,
logo.size.height)];
logoView.image = logo;
[self.navigationBar addSubview:logoView];

Related

QLPreviewController NavigationBar setTranslucent property not working

i have set the custom color to navigation bar of QLPreviewController
but the problem is that i want dark color of navigation bar in QLPreviewController
even i have set the navigation bar translucent property to No
But i Dont know Why it is not working
I want it like belowed image
but it shows like this image
QLPreviewController *previewer = [[QLPreviewController alloc] init];
// Set data source
[previewer setDataSource:self];
[previewer setDelegate:self];
// Which item to preview
[previewer setCurrentPreviewItemIndex:index];
[previewer.view addGestureRecognizer:singleTap];
previewer.navigationController.navigationBar.translucent = NO;
previewer.navigationController.navigationBar.barTintColor = [UIColor redColor];
self.navigationController.navigationBar.translucent=NO;
self.navigationController.navigationBar.barTintColor = [UIColor redColor];
[self.navigationController pushViewController:previewer animated:TRUE ];
even i have also tried like this but it is also not working
- (id <QLPreviewItem>)previewController: (QLPreviewController *)controller previewItemAtIndex:(NSInteger)index
{
// Break the path into it's components (filename and extension)
// Use the filename (index 0) and the extension (index 1) to get path
//lblFileName.text=[strFileName stringByReplacingOccurrencesOfString:#"movefile" withString:#""];
// For navigation bar color and text attributes of navigation bar
for (id object in controller.childViewControllers)
{
if ([object isKindOfClass:[UINavigationController class]])
{
UINavigationController *navController = object;
navController.navigationBar.translucent=NO;
navController.navigationBar.barTintColor = [UIColor redColor];;
navController.toolbar.translucent=NO;
navController.toolbar.barTintColor=[UIColor redColor];;
[navController.navigationBar setTitleTextAttributes:[NSDictionary dictionaryWithObjectsAndKeys:[UIColor whiteColor], NSForegroundColorAttributeName, nil]];
}
}
NSString *strFilename=[[NSBundle mainBundle]pathForResource:#"final" ofType:#"png"];
return [NSURL fileURLWithPath:strFilename];
}
Please suggest me where i am going wrong
Thanks In Advance
The main problem is that when you try to set the translucency of the navigation bar, you haven't pushed the preview controller on the navigation stack yet.
At this point, the preview controller is allocated and instantiated, but its view has not been loaded or added to the view hierarchy, and the value of previewer.navigationController is nil. The value of self.navigationController is not nil at this point, but the translucency property you set here will be overwritten as a side effect of pushing the preview controller. The easiest way to get the effect you want, is to swap the order of the statements, like this:
[self.navigationController pushViewController:previewer animated:YES];
self.navigationController.navigationBar.translucent = NO;
Do note that with the translucency of the navigation bar set to NO, the previewed content will start under the navigation bar, which is probably not what you want. The easiest way to work around that issue, is to set the translucency property after the view of the preview controller has appeared on screen. You can do this by subclassing QLPreviewController:
#interface PreviewController : QLPreviewController
#end
#implementation PreviewController
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
self.navigationController.navigationBar.translucent = NO;
}
Note that things get more complicated when you present the preview controller modally (rather than pushing it on a navigation stack). In that case, there is no navigation controller available to access the navigation bar and you need to rely on the internal view hierarchy of the QLPreviewController. The following code works in iOS7, but might break in a later version:
[self presentViewController:previewController animated:YES completion:^{
UIView *view = [[[previewController.view.subviews lastObject] subviews] lastObject];
if ([view isKindOfClass:[UINavigationBar class]])
{
((UINavigationBar *)view).translucent = NO;
}
}];
No need for subclassing. try this:
QLPreviewController * ql = [[QLPreviewController alloc] init];
...
[self showViewController:ql sender:self];
ql.navigationController.navigationBar.translucent = NO;
ql.edgesForExtendedLayout = UIRectEdgeNone;
If you want to present it modally, just put the previewController into a navigationController:
UINavigationController * navi = [[UINavigationController alloc] initWithRootViewController:ql];
ql.navigationController.navigationBar.translucent = NO;
ql.edgesForExtendedLayout = UIRectEdgeNone;
[self presentViewController:navi animated:YES completion:nil];
Instead of using QLPreviewController,y don't you use webview to load the pdf.But if you load pdf in webview you need to customise the buttons thats it.Its also look very similar to QLPreviewController.
NSURL *targetURL = [NSURL fileURLWithPath:path_pdf]; //path_pdf is pdf's path
NSURLRequest *request = [NSURLRequest requestWithURL:targetURL];
[webview_pdf loadRequest:request];
Well,try it once.
If Still, anyone wants to customize the Navigation bar of QLPreviewController then they can try creating a UIViewController and customize it as per requirement and then create QLPreviewController object and add it as a child view controller.
This will allow you to get rid of share button and you customize navigation bar color etc. this is working for me.
To know, how to add child view controller you can refer to this

ios5.1 adding a UIView on top of iphone statusbar

I am trying to add a view on top of the statusbar. I have been following this SO post: Adding view on StatusBar in iPhone
For some reason, when I create the window and set Hidden to NO, the view does not appear to show up on top of the statusbar. Does this implementation still work in ios5.1?
Thanks!
This is my custom UIWindow class:
#implementation StatusBarOverlay
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
// Place the window on the correct level and position
self.hidden = NO;
self.windowLevel = UIWindowLevelStatusBar+1.0f;
self.frame = [[UIApplication sharedApplication] statusBarFrame];
// Create an image view with an image to make it look like a status bar.
UIImageView *backgroundImageView = [[UIImageView alloc] initWithFrame:self.frame];
backgroundImageView.image = [UIImage imageNamed:#"bar_0.png"];
backgroundImageView.animationImages = [NSArray arrayWithObjects:[UIImage imageNamed:#"bar_1.png"],
[UIImage imageNamed:#"bar_2.png"],
[UIImage imageNamed:#"bar_3.png"],
nil];
backgroundImageView.animationDuration = 0.8;
[backgroundImageView startAnimating];
[self addSubview:backgroundImageView];
}
return self;
}
In my viewcontroller, I created the new window and called this in viewDidLoad:
StatusBarOverlay *overlayWindow = [[StatusBarOverlay alloc] initWithFrame:CGRectZero];
[overlayWindow makeKeyAndVisible];
However, the view still doesn't show up. Any idea as to why?
set your application's window level to UIWindowLevelStatusBar:
self.window.windowLevel = UIWindowLevelStatusBar;
and then add your own view to application window anywhere:
[[[UIApplication sharedApplication]delegate].window addSubview:yourview];
this problem came to me recently, and I just solved it through this way
You can create a new UIWindow and add your view to that. Set the windows frame to [[UIApplication sharedApplication] statusBarFrame] and call makeKeyAndVisible to make it visible.
In the end, I subclassed UIWindow and made that the primary UIWindow in the application AppDelegate. I added any custom view and set the window level to UIWindowLevelStatusBar to display on top of the status bar.

UIPopoverController and UINavigationController cuts corners

I have a problem with the display of my popover. After initWithContentViewController: and presentPopoverFromBarButtonItem:permittedArrowDirections:animated: it cuts corners of the navigation bar. How should I fix it?? Thanks.
This is the code I'm using
NavContr *nav = [NavContr new];
nav.navigationBar.backgroundColor = [UIColor redColor];
UIPopoverController *tempPop = [[UIPopoverController alloc] initWithContentViewController:nav];
[tempPop presentPopoverFromBarButtonItem:mainButtonItem permittedArrowDirections:UIPopoverArrowDirectionUp animated:NO];
EDIT: I have resolved this problem:
+ (void)configure:(UINavigationController *)navController {
UINavigationBar *navigationBar = navController.navigationBar;
UIView *contentView = nil;
for (UIView *view in navController.view.subviews) {
if ([[NSString stringWithFormat:#"%#", [view class]] isEqualToString:#"UILayoutContainerView"])
contentView = view;
}
// setting frame to navigation bar and content view
[navigationBar setFrame:CGRectMake(navigationBar.frame.origin.x, 0, navigationBar.frame.size.width, navigationBar.frame.size.height)];
[contentView setFrame:CGRectMake(contentView.frame.origin.x, 0, contentView.frame.size.width, contentView.frame.size.height + navigationBar.frame.size.height)];
[navController.view bringSubviewToFront:contentView];
for (UIView *customView in contentView.subviews)
customView.frame = CGRectMake(customView.frame.origin.x, customView.frame.origin.y + navigationBar.frame.size.height, customView.frame.size.width, customView.frame.size.height);
[contentView addSubview:navigationBar];
[contentView bringSubviewToFront:navigationBar];
}
This is probably because you have no root view controller, or are otherwise fiddling with the navigation controller in ways it was not meant to be played with. This is how you ought to be setting up the popover:
MyCustomViewController *viewController = [[UIViewController alloc] initWithNibName:#"MyCustomViewController" bundle:nil]; //or storyboard or whatever
UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:viewController]; //you should have a root view controller before displaying the popover
tintColor = [UIColor redColor];
UIPopoverController *tempPop = [[UIPopoverController alloc] initWithContentViewController:nav];
[tempPop presentPopoverFromBarButtonItem:mainButtonItem permittedArrowDirections:UIPopoverArrowDirectionUp animated:NO];
There are a few very important things going on here:
Your navigation controller should have a root view controller before you display it.
This code is using a standard UINavigationController instance. According to the documentation, you should not subclass UINavigationController, nor should you try and reinvent the wheel. Apple has created a complex and comprehensive framework, UIKit, that you can use to build amazing apps. If you try and step outside the box, you'll be creating an awful lot of work for yourself without any appreciable benefit.
This is using the tintColor property of the UINavigationBar class. If the tint is insufficient for your UI, you can also set the background image manually (refer to the docs).
If you want to make a popover with a navigation controller, use the built-in UINavigationController class. Don't subclass it and don't reinvent it. To customize the appearance of the navigationBar, use the UI_APPEARANCE_SELECTOR methods in the UINavigationBar class.
I get the solution before add CALayer the UIPopOverController shows like
after adding below lines in table view class i get the following UIPopOverController
#import <QuartzCore/QuartzCore.h>
CALayer *imageLayer2 = self.tableView.layer;
[imageLayer2 setCornerRadius:-20];
[imageLayer2 setBorderWidth:1];
Try it in your project may be it works!!
Thanx
I have tried & replicate the issue you are facing, made some R&D. It's due to the line of code below :
nav.navigationBar.backgroundColor = [UIColor redColor];
While you set the background color of the navigation bar it will behave weird due the native shape of the pop up. Try and remove the below line, you will definitely have issue resolved.
If you are specifying the Rect where the popover appears, we've found that using decimals can result in weird distortions like that. Be sure you're using whole number for origin and size.

Creating a UITabBar With a Normal UIViewController(Not UITabBarController)

I have a UIViewController and I wish to place a simple UITabBar like the in the screenshot below: I don't want to use an UITabBarController. In fact, my original setup uses one, and it's easy as cake to get it to work.
However, the thing is I found out it's a bad idea to put UITabBarControllers inside Navigation Controllers, so I'm forced to refactor the hierarchy (so please don't suggest using one).
Given an UIViewController, how can I add an UITabBar on the bottom programatically? I got my UITabBarDelegate all setup to show a specific view when 1 of the tab bars is clicked, but the problem is when the view controller loads, no tab bar shows up! Here's my code to do that:
- (void) viewDidLoad {
...some initialization...
CGRect frame = CGRectMake(0, 431, 320, 49);
profileItem = [[UITabBarItem alloc] init];
profileItem.image = icon;
profileItem.title = #"Diet";
tabBar = [[UITabBar alloc] initWithFrame:frame];
NSArray* items = [[NSArray alloc] initWithObjects:profileItem, nil];
tabBar.items = items;
tabBar.delegate = self;
[tabBar setSelectedItem:[tabBar.items objectAtIndex:0]];
[self.view addSubview:tabBar];
[super viewDidLoad];
}
What am I missing here?
EDIT: Argh, I found out it has to do with the frame... Hmm.. what y-coordinate should I use if I have an existing navigation header on top?
You mention in your edit that you already determined that it has to do with the frame. Your problem may stem from the fact that your view's size in viewDidLoad isn't guaranteed to be the same is it will be when it eventually gets displayed. UIKit resizes the view to fit the context in which it's being displayed just before viewWillAppear:.
If you want to add the tab bar in viewDidLoad, then you should position it at the bottom of your view's frame by doing some math:
CGRect frame = CGRectMake(0, self.view.bounds.size.height - 49,
self.view.bounds.size.width, 49);
Then set an appropriate autoresizingMask so that it remains at the bottom even if UIKit resizes your view:
tabBar.autoresizingMask = UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleWidth;

Custom UINavigationBar Background

I've been trying to set up a custom background for the whole of my NavigationBar (not just the titleView) but have been struggling.
I found this thread
http://discussions.apple.com/thread.jspa?threadID=1649012&tstart=0
But am not sure how to implement the code snippet that is given. Is the code implemented as a new class? Also where do I instatiate the UINavigationController as I have an application built with the NavigationView template so it is not done in my root controller as per the example
Uddhav and leflaw are right. This code works nicely:
#interface CustomNavigationBar : UINavigationBar
#end
#implementation CustomNavigationBar
-(void) drawRect:(CGRect)rect
{
UIImage *image = [UIImage imageNamed: #"myNavBarImage"];
[image drawInRect:CGRectMake(0, 0, self.frame.size.width, self.frame.size.height)];
}
#end
// this can go anywhere
+(UINavigationController*) myCustomNavigationController
{
MyViewController *vc = [[[MyViewController alloc] init] autorelease];
UINavigationController *nav = [[[NSBundle mainBundle] loadNibNamed:#"CustomNavigationController" owner:self options:nil] objectAtIndex:0];
nav.viewControllers = [NSArray arrayWithObject:vc];
return nav;
}
You have to create CustomNavigationController.xib and put a UINavigationController in it and change the navigationBar class to "CustomNavigationBar".
You must use the 'appearance' proxy to change the background and other styling properties of controls such as UINavigationBar, UIToolBar etc. in iOS 5.xx. However, these are not available for iOS 4.xx so for backwards compatibility, you need a hybrid solution.
If you want to support both iOS 4.xx and iOS 5.xx devices (i.e. your DeploymentTarget is 4.xx), you must be careful in wrapping the call to the appearance proxy by checking at runtime if the 'appearance' selector is present or not.
You can do so by:
//Customize the look of the UINavBar for iOS5 devices
if ([[UINavigationBar class]respondsToSelector:#selector(appearance)]) {
[[UINavigationBar appearance] setBackgroundImage:[UIImage imageNamed:#"NavigationBar.png"] forBarMetrics:UIBarMetricsDefault];
}
You should also leave the iOS 4.xx workaround that you may have implemented. If you have implemented the drawRect workaround for iOS 4.xx devices, as mentioned by #ludwigschubert, you should leave that in:
#implementation UINavigationBar (BackgroundImage)
//This overridden implementation will patch up the NavBar with a custom Image instead of the title
- (void)drawRect:(CGRect)rect {
UIImage *image = [UIImage imageNamed: #"NavigationBar.png"];
[image drawInRect:CGRectMake(0, 0, self.frame.size.width, self.frame.size.height)];
}
#end
This will get the NavBar look the same in both iOS 4 and iOS 5 devices.
You just have to overload drawRect like that :
#implementation UINavigationBar (CustomImage)
- (void)drawRect:(CGRect)rect {
UIImage *image = [UIImage imageNamed: #"NavigationBar.png"];
[image drawInRect:CGRectMake(0, 0, self.frame.size.width, self.frame.size.height)];
}
#end
Implementing a category is not advisable. iOS5 may provide relief for this issue. But for old APIs, you can -
Subclass UINavigationBar to say CustomNavBar and implement the custom drawRect from Lithium's answer.
For all IB based UINavigationControllers, provide CustomNavBar as custom class for their UINavigationBar.
For all code based UINavigationControllers. Create a XIB with a UINavigationController and do step two. Then provide a factory method in code that loads the UINavigationController from the nib and provide an IBOutlet.
Eg.
[[NSBundle mainBundle] loadNibNamed:#"CustomNavigationController" owner:self options:nil];
UINavigationController *navController = self.customNavigationController;
navController.viewControllers = [NSArray arrayWithObject:controller]
You can also override the drawLayer:inContext: method in a UINavigationBar category class. Inside the drawLayer:inContext: method, you can draw the background image you want to use.
- (void) drawLayer:(CALayer *)layer inContext:(CGContextRef)context
{
if ([self isMemberOfClass:[UINavigationBar class]] == NO) {
return;
}
UIImage *image = (self.frame.size.width > 320) ?
[UINavigationBar bgImageLandscape] : [UINavigationBar bgImagePortrait];
CGContextClip(context);
CGContextTranslateCTM(context, 0, image.size.height);
CGContextScaleCTM(context, 1.0, -1.0);
CGContextDrawImage(context, CGRectMake(0, 0, self.frame.size.width, self.frame.size.height), image.CGImage);
}
And as a complete demo Xcode project on customizing the appearance of UINavigationBar this and this might be helpful.
Implementing a category won't work in iOS5, you should use Uddhav Kambli's advice for using CustomNavbar on iOS ≤ 5.
I just found this blog entry, describing this topic very simple: http://web0.at/blog/?p=38
it helped me a lot, they use the "drawRect" method to get the customisation of the background.
To all those who are having trouble with UINavigationBar custom backgrounds in iOS5, do this in the corresponding viewDidLoad methods:
#if defined(__IPHONE_5_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_5_0
if ([self.navigationController.navigationBar respondsToSelector:#selector( setBackgroundImage:forBarMetrics:)]){
[self.navigationController.navigationBar setBackgroundImage:[UIImage imageNamed:#"TitleBar"] forBarMetrics:UIBarMetricsDefault];
}
#endif
Notice that in my case, the background image was named "TitleBar". You can put whatever your custom background image name is.
The problem you'll have is that if you use a navigation controller, the title of each page will overlay your custom navbar. If your navbar contains a logo or the name of your app, this is obviously unacceptable.
You could set the title of each view in your navigation stack to blank, but some views force a title that you can't do anything about (like the photo picker). So you might want to create an alternate navbar image with the same color or design as your logo navbar, but with a blank area to make room for overlaid titles.
To switch navbar images at will, add a property to your app delegate to hold the name of the navbar image and replace the first line of the first example above with these two:
YourAppDelegate* theApp = (YourAppDelegate*)[[UIApplication sharedApplication] delegate];
UIImage* image = [UIImage imageNamed:theApp.navBarName];
Then in the first view controller that you'll push onto the navigation stack, do something like this:
- (void)viewWillAppear:(BOOL)animated
{
YourAppDelegate* theApp = (YourAppDelegate*)[[UIApplication sharedApplication] delegate];
theApp.navBarName = #"navBar_plain";
}
Then in the root view controller, do the same thing but specify your logo-bearing navbar image, so it gets restored when the user navigates back to it and there is no conflicting title.
Another approach is to Use UINavigationController's delegate.
It doesn't require subclassing/overwriting the UINavigationBar class:
/*
in the place where you init the navigationController:
fixer = [[AENavigationControllerDelegate alloc] init];
navigationController.delegate = fixer;
*/
#interface AENavigationControllerDelegate : NSObject <UINavigationControllerDelegate>
#end
#implementation AENavigationControllerDelegate
#define bgImageTag 143
- (void)navigationController:(UINavigationController *)navigationController
didShowViewController:(UIViewController *)viewController
animated:(BOOL)animated
{
//this is for the future for implementing with the appearance api:
if ([[navigationController navigationBar] respondsToSelector:#selector(setBackgroundImage:forBarMetrics:)])
{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
[[navigationController navigationBar] setBackgroundImage:[UIImage imageNamed:#"header-logo-bg.png"]
forBarMetrics:UIBarMetricsDefault];
});
}
else
{
UIImageView* imageView = (UIImageView*)[navigationController.navigationBar viewWithTag:bgImageTag];
if(!imageView)
{
UIImage *image = [UIImage imageNamed:#"header-logo-bg.png"];
imageView = [[[UIImageView alloc] initWithImage:image] autorelease];
imageView.tag = bgImageTag;
}
[navigationController.navigationBar insertSubview:imageView atIndex:0];
}
}
#end
https://gist.github.com/1184147
In iOS5, zPosition value (of UINavigationBar's most depth layer) is changed. So if you change that zPosition, the old way works.
eg.
UINavigationBar *_bar = navigationController.navigationBar;
// Insert ImageView
UIImage *_img = [UIImage imageNamed:#"navibar.png"];
UIImageView *_imgv = [[[UIImageView alloc] initWithImage:_img] autorelease];
_imgv.frame = _bar.bounds;
UIView *v = [[_bar subviews] objectAtIndex:0];
v.layer.zPosition = -FLT_MAX;
_imgv.layer.zPosition = -FLT_MAX+1;
[_bar insertSubview:_imgv atIndex:1];
This script handle view's layer, so You should import QuartzCore.
Here is an alternative solution that lets you use your own custom subclass of UINavigationBar:
https://gist.github.com/1253807
As Apple itself has said, it is not correct to override methods in Categories. So the best way to customize the background of UINavigarionBar is subclassing and override -(void)drawInRect: method.
#implementation AppNavigationBar
- (void)drawRect:(CGRect)rect
{
UIImage *patternImage = [UIImage imageNamed:#"image_name.png"];
[patternImage drawInRect:rect];
}
To use this customized UINavigationBar it should be set as navigationBar property of your UINavigationBarController. As you know this property is readonly. So what should be done is:
- (void)viewDidLoad
{
[super viewDidLoad];
AppNavigationBar *nav = [AppNavigationBar new];
[self setValue:nav forKey:#"navigationBar"];
}
It works for both iOS 5 and 4.3.
You can subclass UINavigationBar and enable it like this, since categories for drawRect won't work in iOS5 anymore
navigationController = [[((^ {
NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:[NSKeyedArchiver archivedDataWithRootObject:navigationController]];
[unarchiver setClass:[SAPHUINavigationBar class] forClassName:#"UINavigationBar"];
[unarchiver setClass:[UIViewController class] forClassName:NSStringFromClass([navigationController.topViewController class])];
return unarchiver;
})()) decodeObjectForKey:#"root"] initWithRootViewController:navigationController.topViewController];
For a static view (no animation at all), I use the default iOS setBackgroundImage
But when I have a view that's animated (resize most likely), I create a custom UIImageView and add it to the navigationBar so that I have more flexibility over it
The thing is if you just add it, it will get on top of the buttons and the titleView, so I manually save a copy of most of subviews, remove them from parent view, add my imageView and than add all the subviews back
This works for me
UIImageView *navBackground = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"navigationBackgroundSample.jpg"]];
UIView *tempTitleView = [[self.navigationBar.subviews objectAtIndex:1] autorelease];
[[self.navigationBar.subviews objectAtIndex:1] removeFromSuperview];
[self.navigationBar addSubview:navBackground];
[self.navigationBar addSubview:tempTitleView];
self.navigationBar.clipsToBounds = YES;
[navBackground release];
In this case, I don't have buttons and I found out that my titleView is at index 1, if you have buttons, they should be around somewhere in the subviews array of navigationBar
I don't know what's at index 0, I don't know if this can work around the case you have text title neither...