views:

379

answers:

1

I'm having some problems resizing a UITabBarController as I only want it to take up the bottom half of the screen. It seems to force itself to display the full height of the screen (minus the status bar if showing).

I have tried subclassing it and modifying the controller's view's frame on methods such as viewWillAppear; but it's just doesn't work. There are occasions where I can force it's position to be altered, but as soon as another tab is selected, or if another view controller is presented modally in front of it, it resizes back to full screen!

I've tried setting the UIWindow (which the tab bar controller is added to) to autoresizesSubviews:NO and the tab bar's autoresizingMask:UIViewAutoresizingNone but that doesn't do it!

Any help would be greatly appreciated!

+1  A: 

I've experimented with this and determined that the tabBarController will automatically resize its view and undo all your changes when any of the following happens:

  • value of selectedViewController changes;
  • interface orientation changes;
  • the tab bar is (re)loaded and placed inside a view/window.

I was able to force the UITabBar's view to remain of constant size by registering for all of the above events and then calling a custom resizing method from them.

You can observe changes to the selectedViewController with KVO, like so:

[tabBarController addObserver:self forKeyPath:@"selectedViewController" options:NSKeyValueObservingOptionNew context:NULL]

Observing changes to the interface orientation can be a bit tricky. If you're doing this from your application delegate, or another object dedicated to this purpose, chances are you're not getting the standard UIViewController callbacks for interfare orientation changes. There are two ways to work around this: (1) UIDevice and notifications, and (2) getting one of your view controllers to generate a callback. Personally, I would recommend the latter, as the UIDevice notifications tend to be a few microseconds out of sync with the interface, and the result can look jaggy. Simplified implementation:

// In a header somewhere (Prefix.pch works).

extern NSString *const kOrinetationNotification;
extern NSString *const kOrinetationNotificationOrientationKey;

// in an instance of UIViewController

- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
  [[NSNotificationCenter defaultCenter] postNotificationName:kOrientationNotification object:self userInfo:[NSDictionary dictionaryWithObject:[NSNumber numberWithInt:toInterfaceOrientation] forKey:kOrientationNotificationOrientationKey]];
  // do other stuff
}

// in your application delegate's (or other dedicated object) init method

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(orientationDidChange:) name:kOrientationNotification object:nil];

This should make sure you get heads up every time something triggers a change in your tab bar's geometry. Once you're receiving these callbacks, you can call your own custom method from each of them and resize the tab bar as you see fit with no need to subclass it.

Adam
Thanks for this, I'll give it a shot and see if it works!
Michael Waterfall