How to create an UIViewController with UINavigationController with Interface Builder?

14,023

Solution 1

When you init a view controller from a nib, it does not actually load the nib right away, so viewSettings.navigationController is still nil. The first time you reference the view property, the nib will be loaded.

Update

You could load the nib yourself and grab the navigation controller, like so:

UINavigationController *navController = [[[NSBundle mainBundle] loadNibNamed:@"ViewSettings" owner:self options:nil] objectAtIndex:1];

I used object at index 1 because in your screenshot there's a tableview which I think will be index 0.

Solution 2

It would be helpful if you were to show the contents of your nib file because I suspect viewSettings.navigationController is nil. navigationController is a property of all UIViewControllers which gives you their parent navigation view controller, if one exists. It sounds like you never added your viewSettings view controller to a navigation controller's stack of view controllers.

Share:
14,023
Manni
Author by

Manni

mobile development

Updated on June 04, 2022

Comments

  • Manni
    Manni almost 2 years

    In my iOS application, I want to provide a settings-view. "presentModalViewController" works very well:

    ViewSettings *controller = [[ViewSettings alloc] initWithNibName:@"ViewSettings" bundle:nil];
    UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:controller];
    [self.navigationController presentModalViewController:navController animated:YES];      
    [controller release];
    [navController release];
    

    Unfortunately, I have to change my running code and create the ViewSettings including the UINavigationController in Interface Builder. Why? Long story, I'll explain it in the end of this thread...

    I try to drag and drop an UINavigationController in my ViewSettings and create an IBOutlet to access it in my class. I give this controller to "presentModalViewController" but the application crashed...

    What I'm doing wrong?


    [EDIT]

    Error Message: GDB: Program received signal: "SIGABRT".
    The error happens in the last line of this code:

    ViewSettings *viewSettings = [[ViewSettings alloc] initWithNibName:@"ViewSettings" bundle:nil];
    UINavigationController *navController = viewSettings.navigationController;
    UINavigationBar *navBar = navController.navigationBar;
    OwnNavigationBar *ownNavBar = (OwnNavigationBar *)navBar;
    [ownNavBar drawHeaderImage:YES];
    [self.navigationController presentModalViewController:navController animated:YES];
    

    Detailed Error: Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Application tried to present a nil modal view controller on target .'

    [/EDIT]


    [EDIT2]
    Thanks for your help! Yes, navigationController is nil... I think I add the UINavigationController in a wrong way... I put it in this window, because it was not possible to put it directly in my view: alt text
    How do I add the UINavigationController correct?
    [/EDIT2]


    PS: Why do I have to use IB? (you can skip this...)

    I need an background image in my UINavigationBar. My first try was:

    UIImage *image = [UIImage imageNamed: @"header.png"];
    UIImageView *imageView = [[UIImageView alloc] initWithImage:image];
    [self.navigationController.navigationBar addSubview:imageView];
    [self.navigationController.navigationBar sendSubviewToBack:imageView];
    

    But in some issues, the title oder a UIBarButton is not visible! I tried a lot, e.g. sets the "tag" of the view and sendSubviewToBack in each view, but no success. This is a very annoying bug!

    My second try was to create a category and overwrite the drawRect-method:

    @implementation UINavigationBar(MyNavigationBar)
    - (void)drawRect:(CGRect)rect {
        UIImage *image = [UIImage imageNamed: @"header.png"];
        [image drawInRect:CGRectMake(0, 0, self.frame.size.width, self.frame.size.height)];
    }
    @end
    

    But now, all of my UINavigationBars have an background image and I can't deactivate it. The problem is, that "ViewSettings" needs the background image, but the following pushed views do not.

    Unfortunately, it isn't possible to set a property in a category or call [super drawRect:rect] to avoid painting the image.

    My last try is to write an own UINavigationBar

    @interface OwnNavigationBar : UINavigationBar {
        BOOL _drawHeaderImage;
    }
    

    Now I can control the drawRect-method!! GREAT!!

    - (void)drawRect:(CGRect)rect {
        if (_drawHeaderImage) {
            UIImage *image = [UIImage imageNamed: @"header.png"];
            [image drawInRect:CGRectMake(0, 0, self.frame.size.width, self.frame.size.height)];
        }
        else {
            [super drawRect: rect];
        }
    }
    

    But I celebrate to early... :-( It isn't possible to set an own UINavigationBar in the UINavigationController!!! "navigationBar" in UINavigationController is a read-only property! AAAAHHHHHHHHHH!

    I have one last chance: in Interface Builder it is possible to give an UINavigationController an own UINavigationBar!! YES! I GOT IT!! :-)

    I configured it in my MainWindow_iPhone.xib and it works great! Now, I have to implement this for my ViewSettings, because this (modal) view needs a new UINavigationController.

    PS: Maybe, someone can send this thread to Apple, this all are very annoying circumstances and bugs :-(