Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Non-fullscreen UINavigationController

Is it possible to use a UINavigationController in such a way that it doesn't use the full window?

I've tried setting it's view's frame as well as adding it's view to another (non-fullscreen) view instead of the window, and neither seems to work.

like image 301
Jaka Jančar Avatar asked Jun 02 '10 22:06

Jaka Jančar


2 Answers

You cannot directly change the size of a UINavigationController or it's subviews directly, as the UINavigationController automatically resizes them to full screen, no matter what their frames are set to. The only way I've been able to overcome this so far is as follows:

First, create an instance of UINavigationController as you normally would:

UINavigationController *nc = [[UINavigationController alloc] init];
self.navController = nc;
[nc release];

Then, create an instance of UIView, constrained to the size you really want:

UIView *navView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, DESIRED_HEIGHT)];
navView.clipsToBounds = YES;
[navView addSubview:self.navController.view];   
[self.view addSubview:navView];
[navView release];

The navView's clipsToBounds property must be set to YES, or the UINavigationController and it's view will still appear fullscreen. Then, add the UINavigationController to that constrained view. This UIView may then be added to the UIViewController's view, as seen above.

The thing to note is that any UIViewController's views that are added to the UINavigationController will all have their content constrained to navView's bounds, not the frame of the subviews added to the UINavigationController, so the content in each subview should be created to properly display for the navView's bounds.

In any case, this technique does work, as I've created an app that successfully uses it. The only other way I've ever gotten this to work is to create a custom navigation controller class from scratch, replicating the functionality of UINavigationController, but without the automatic resizing (which I've also done in the past), and that can be a pain. Hope this helps.

like image 76
Ashwin Avatar answered Nov 15 '22 05:11

Ashwin


This is my first post ever, although I have been learning an enormous amount from this community. So I wanted to thank you all for this.

My challenge, and the reason I'm posting here, was to take the answer to this question and refactor it for my needs, using iOS5 and storyboards. This solution probably won't work well for older implementations, but I thought I'd post it anyway.

Here's what I ended up with, and it works well (iPad app). This is all set up on my default UIViewController, set as root in storyboard view.

Hope this helps out!

- (void)viewDidLoad
{
    [super viewDidLoad];



    // Do any additional setup after loading the view, typically from a nib.

    /*vars: 
     rightSideView is the containing view - this is where the UINavigationController will sit, along with it's view stack
     myStoryboard is self-explanatory I think
     myViewController is identified as in storyboard as "accountView", to be pulled from the storyboard and used as the rootview
     */


    //Steps

    //Add subview to this controller's view (for positioning)


    UIView *rightSideView = [[UIView alloc]initWithFrame:CGRectMake(30, 30, 500, 600)];
    rightSideView.clipsToBounds = YES;//this little baby makes sure that the damn navigation bar clips!!

    rightSideView.backgroundColor = [UIColor grayColor];//so I can see it

    //instantiate view controller for nav controller's root view
    UIStoryboard *myStoryboard = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:[NSBundle mainBundle]];
    UIViewController *myViewController = [myStoryboard instantiateViewControllerWithIdentifier:@"accountView"];

    //create NavController
    UINavigationController *myNavController = [[UINavigationController alloc]initWithRootViewController:myViewController];

    //Add navController as one of my child ViewControllers

    [self addChildViewController:myNavController];

    //Add NavController's view into my constrained view
    [rightSideView addSubview:myNavController.view];

    //Finally, add right side view as a subview of myself
    [self.view addSubview:rightSideView];



}
like image 44
user1305843 Avatar answered Nov 15 '22 05:11

user1305843