Centurion
Centurion

Reputation: 14314

How do I set custom navigation bar(title + titleView) for all navigation controllers and view controller?

I have a tabbed application with navigation controllers in tabs and view controller in them. All of them use the same navigation controller navigation bar: back button + logo image. Currently, I'm placing this code in every view controller:

- (void)viewDidLoad
{
  [super viewDidLoad];
  self.navigationItem.title = @"Back";
  UIImage *headerImage = [UIImage imageNamed:@"Logo.png"];
  self.navigationItem.titleView = [[[UIImageView alloc] initWithImage:headerImage] autorelease];
}

IMHO it's not the best way to do that. I'm thinking about using a category for UIViewController and to override viewDidLoad method, but every view controller has some additional code to execute in viewDidLoad, so I guess overriding is not the solution. What are the other ways?

Upvotes: 3

Views: 7106

Answers (2)

Werner Altewischer
Werner Altewischer

Reputation: 10474

In proper architecture a UIViewController (or sub class) should not care in which context it is displayed (e.g. within a UINavigationController, UITabController, modal or not). Consider using the coordinator pattern where it's the coordinator's responsibility to perform this kind of configuration.

Example:

class FlowCoordinator {
    ...

    // The coordinator knows about the navigation controller
    // Individual view controllers do not.
    private let navigationController: UINavigationController

    func presentViewController(viewController: UIViewController) {
        // This setup can be common for all view controllers in this flow
        viewController.navigationItem.titleView = ...
        viewController.backBarButtonItem = ...
        viewController.navigationItem.title = ...
        navigationController.pushViewController(viewController)
    }

    ...
}

Upvotes: 0

Mike Weller
Mike Weller

Reputation: 45598

You could create a subclass of UIViewController, MyViewControllerWithBackButtonAndLogo (you can come up with a better name) then implement viewDidLoad to set up the navigation item. Make all your view controllers inherit from this base class. Then just make sure the view controllers call [super viewDidLoad] in their own implementations.

Also note that to set the back button title, you should not change the navigation item's title property, but set an appropriate backBarButtonItem.

Upvotes: 9

Related Questions