Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Idiom for Initializing UINavigationItem

Since UIViewController navigationItem outlets are deprecated (yes, I'm a bit behind), what is the correct idiom specifying the elements of a UINavigationItem?

I've seen several approaches suggested, but none are entirely clear to me:

  1. "Embed the navigation item in the view controller" in the view controller's XIB.

  2. Initialize the navigation item's properties in code, with from-scratch values.

  3. Create an outlet for the navigation controller in the view controller, wire up a navigation item in the view controller's XIB, and use its properties to initialize the (actual) navigation item's properties in code.

It isn't clear to me how to "embed" the navigation item (simply adding it as a child of the view controller in IB has no effect); and it isn't clear to me which of these approaches is better, or, for that matter, where (in what method) to do 2 or 3.

like image 227
orome Avatar asked Feb 24 '23 20:02

orome


2 Answers

1) If controller is created in XIB you can drop UINavigationItem on it and tweak this item - it will work. For example when you're defining UINavigationControler in XIB you can put some controller inside as root view controller. So you can have UINavigationItem for this controller in XIB.

2) If controller loads it's view from XIB (it was created by alloc and then init or initWithNibName:bundle:) it's presented in XIB only as File's Owner which doesn't support UINavigationItem in it. In this case you should configure navigation item in code (I do it in viewDidLoad usually). There is no need to create it, it's already there in navigtionItem property of your controller

self.navigationItem.title = @"Price List";

Maybe it's possible to make outlet for navigation item but I wouldn't recommend this. Apple declared such outlet obsolete for a reason. I remember discussing this with co-worker one day, but I forgot what it was (it was obvious then).

like image 172
hoha Avatar answered Apr 02 '23 10:04

hoha


On our project we have a requirement to make UI be as customizable from IB as possible. So, I add UINavigationItem to xib, configure it, link it as outlet to my custom UIViewController subclass, and then copy all properties at runtime with method added to UIViewController using category:

- (void)setNavigationItemPropertiesFromOtherItem:(UINavigationItem *)navItem 
{
    // WORKAROUND: we can't link UINavigationItem to UIViewController from IB, and navigationItem property in UIViewController is readonly
    self.navigationItem.title = navItem.title;
    self.navigationItem.prompt = navItem.prompt;
    self.navigationItem.hidesBackButton = navItem.hidesBackButton;
    if (navItem.backBarButtonItem != nil) 
    {
        self.navigationItem.backBarButtonItem = navItem.backBarButtonItem;
    }
    if (navItem.leftBarButtonItem != nil)
    {
        self.navigationItem.leftBarButtonItem = navItem.leftBarButtonItem;
    }
    if (navItem.rightBarButtonItem != nil)
    {
        self.navigationItem.rightBarButtonItem = navItem.rightBarButtonItem;
    }
    if (navItem.titleView != nil)
    {
        self.navigationItem.titleView = navItem.titleView;
    }
}

This workaround also allows to link bar button items to UINavigationItem using IB.

like image 27
zubko Avatar answered Apr 02 '23 11:04

zubko