UINavigationController's navigation bar wont shrink when in Landscape mode - iphone

My navigation controller's navigation bar won't change the height when rotated to landscape.
see it stays at 44 pixels instead of 34 i think.
What do i do to fix this?

You have to add your navigation controller directly as a subview to your window, otherwise this doesn't work automatically. (It is not necessary to change the frame of your navigation bar manually.)
The -[application:didFinishLaunchingWithOptions:] method of your AppDelegate should contain something like
[window addSubview:self.yourNavController.view];
To get an example where this works automatically, you can also create a new navigation-based app in XCode and add an implementation for the shouldAutorotateToInterfaceOrientation: method of the RootViewController that always returns YES.

During the autoRotation method of your class, change the frame of your navBar like this:
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
if((self.interfaceOrientation == UIInterfaceOrientationLandscapeLeft) || (self.interfaceOrientation == UIInterfaceOrientationLandscapeRight))
{
self.navigationController.navigationBar.frame = CGRectMake(0,0,480,32);
}
else if((self.interfaceOrientation == UIInterfaceOrientationPortrait) || (self.interfaceOrientation == UIInterfaceOrientationPortraitUpsideDown))
{
self.navigationController.navigationBar.frame = CGRectMake(0,0,320,44);
}
else
{
assert(false);
}
}

Related

Rotating UIViewController Problem

I have the following code to display a UIViewController in horizontal orientation ontop of a UITableViewController.
-(void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
if (toInterfaceOrientation == UIInterfaceOrientationLandscapeLeft ||
toInterfaceOrientation == UIInterfaceOrientationLandscapeRight) {
[self.view addSubview:landscapeChartViewController.view];
}
if (toInterfaceOrientation == UIInterfaceOrientationPortrait ||
toInterfaceOrientation == UIInterfaceOrientationPortraitUpsideDown) {
if(landscapeChartViewController != nil)
[landscapeChartViewController.view removeFromSuperview];
}
}
When the phone rotates, the view doesn't take up the entire screen.
The user is also able to scroll, thus showing the rest of the UITableViewController. I don't want the UITableViewController to be there in horizontal orientation.
Try [self.view addSubview:landscapeChartViewController.view];
Assuming you've set your frames correctly, this should be what you're looking for.
landscapeChartViewController.view.frame = self.view.bounds, perhaps?
Also keep in mind that the orientation change can happen "in the background" if you're using a tab bar controller, so you might also want to check the current orientation in -viewWillAppear:.

Changing iphone orientation, then changing it back cuts my view in half?

I have a view controller in my iphone app setup so that when I change the orientation from portrait to landscape, I change the view. When I change the orientation back from landscape to portrait, the initial view comes back, except this time it is all crammed into the left hand side of the screen. Eventually, when I change orientations enough times everything disappears completely. Is this a common issue beginners have? What could I be doing wrong?
In my root controller I am allowing the orientation to change only when a specific view is being shown with this:
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
if (self.currentView == (NSInteger*)Chart || self.currentView == (NSInteger*)Detail) {
return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
}
return (interfaceOrientation == UIInterfaceOrientationPortrait);
Where self.currentView is an enum of what view I currently have up. The Detail view I want to make sure stays as a portrait view, but when I change the orientation while on that view I want it to change the view to the Graph. Again, this works fine the first time, but when I change back from Graph to Detail, it crams all the controls on the Detail view to the left hand side of the screen.
Here is how I'm changing the view:
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration{
if (self.currentView == (NSInteger*)Detail && (toInterfaceOrientation == UIInterfaceOrientationLandscapeLeft || toInterfaceOrientation == UIInterfaceOrientationLandscapeRight)) {
[[NSNotificationCenter defaultCenter] postNotificationName:#"changeView" object:self userInfo:[NSDictionary dictionaryWithObject:[NSNumber numberWithInt:Chart] forKey:#"view"]];
}
if (self.currentView == (NSInteger*)Chart && (toInterfaceOrientation == UIInterfaceOrientationPortrait)) {
[[NSNotificationCenter defaultCenter] postNotificationName:#"changeView" object:self userInfo:[NSDictionary dictionaryWithObject:[NSNumber numberWithInt:Detail] forKey:#"view"]];
}
#justin I once did this which got me into same situation as you are. May be you can check if you haven't done something like this
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
CGRect rect;
if (interfaceOrientation == UIInterfaceOrientationPortrait || interfaceOrientation == UIInterfaceOrientationPortraitUpsideDown) {
rect = CGRectMake(tableView.frame.origin.x,tableView.frame.origin.y,
tableView.frame.size.width - 50, tableView.frame.size.height - 30);
}
else {
rect = CGRectMake(tableView.frame.origin.x,aBar.frame.origin.y,
tableView.frame.size.width, tableView.frame.size.height);
}
[tableView setFrame:rect];
return YES;
}
All I wanted was a table view with small frame in Portrait mode, without saving the original Frame I was trying to reduce its width and height which eventually brought the table view to a very small size after multiple rotation..
Lolzzz. I should have first saved the original tableview frame and then done something like this
if (interfaceOrientation == UIInterfaceOrientationPortrait || interfaceOrientation == UIInterfaceOrientationPortraitUpsideDown) {
tableView.frame = CGRectMake(tableView.frame.origin.x,tableView.frame.origin.y,
tableView.frame.size.width - 50, tableView.frame.size.height - 30);
}
else {
tableView.frame = originalTableViewFrame;
}
check if you have autoresizeSubviews ON (in XIB/Inteface Builder) on your view and possibly parent views and try to turn it off if you are changing frame manually , this solved it for my case

iPhone - Alternate Landscape View issue

I'm having the landscape mode issue and I can not find the way out. Basically, I'm having a tab bar application and in the first tab i have navigation controller. In this navigation controller, first view contains table with items and after clicking the item, detail view describing the item is pushed.
I need to implement landscape mode for both list and detail view, but for list view, i need to use different view controller for landscape mode (generally, something like cover flow). Detail view is just changing orientation and no need to use alternate view controller in this case.
I tried to achieve this behaviour by implementing modal view controller for list view controller, according to Alternate Views example by Apple. This works fine when I'm in list view (when I turn device into landscape mode, cover flow view controller is correctly presented). Problem comes when I'm showing detail view. When I change the device orientation, cover flow shows up again. What I expected is that cover flow will be presented only in case that list view is on the screen. It seems like modal view controller is always visible no matter what VC is currently on the stack of NC.
It seems to me that presenting modal VC as landscape view for particular VC is not working for multiple navigation levels.
I also tried to add landscape view as a subview into view controllers view. When using this solution, i have no problem with navigation levels, but issue here is that tab bar is not hidden in landscape mode. I need to hide tab bar for cover flow, which is achieved by presenting modal VC.
I will appreciate any help with this issue.
Great thanks!
In the detail view controller, you could set up a different view entirely using something like this (code from a recent project of mine):
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toOrientation
duration:(NSTimeInterval)duration
{
if ([graphView superview]) {
if (toOrientation == UIInterfaceOrientationPortrait ||
toOrientation == UIInterfaceOrientationPortraitUpsideDown) {
[graphView removeFromSuperview];
}
} else {
if (toOrientation == UIInterfaceOrientationLandscapeLeft ||
toOrientation == UIInterfaceOrientationLandscapeRight) {
[[self view] endEditing:YES];
[[self view] addSubview:graphView];
}
}
}
And now to hide the tabbar when you are in landscape (bit of a hack, but works):
-(void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation
{
UIInterfaceOrientation toOrientation = self.interfaceOrientation;
if ( self.tabBarController.view.subviews.count >= 2 )
{
UIView *transView = [self.tabBarController.view.subviews objectAtIndex:0];
UIView *tabBar = [self.tabBarController.view.subviews objectAtIndex:1];
if(toOrientation == UIInterfaceOrientationLandscapeLeft ||
toOrientation == UIInterfaceOrientationLandscapeRight) {
transView.frame = CGRectMake(0, 0, 480, 320 );
tabBar.hidden = TRUE;
}
else
{
transView.frame = CGRectMake(0, 0, 320, 480);
tabBar.hidden = FALSE;
}
}
}
For this project, I added a view called "graphView" that I wanted to appear if and only if in landscape mode, and then I wanted to tabbar to be hidden. This sounds similar to what you're after, I think.
The only potential problem I foresee is that if you enter landscape mode before the detail view is pushed, things could get wonky. Therefore you may want to use these methods in the list view controller instead. This particular problem never arose for me, but it's something I thought about before I realized it was moot.

How to set the content size according to the size of UINavigation bar

I am resizing the navigation bar when my application switches into landscape orientation.
But i am not able to set the content size of navigation bar according to its height.
Landscape image :- In this image the top left bar item and title of navigation bar are not resizing when it switches into landscape orientation....they should get re sized according to height of navigation bar.
Please suggest me any idea for it?
Thanks
Deepika
override the method:
- (UIView *)rotatingHeaderView
{
return yourNavigationBar;
}
this method will get called when your device orientation takes place.
-(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
if(mainLoginView.superview == self.view || modulesView.superview == self.view)
{
return NO;
}
else
{
return YES;
}
}
replace this method with your code and reply me what happens :)
I am doing in this delegate method:-
-(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation{
if(mainLoginView.superview == self.view || modulesView.superview == self.view){
return NO;
}else{
[self rotateTheNavigation:contactsNavigation withOrientation:interfaceOrientation];
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
}
If you have to recalculate your views, you'd better put your code into
-
(void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation
duration:(NSTimeInterval)duration,
or -(void)
didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation
shouldAutorotateToInterfaceOrientation is only supposed to respond to the question : "This view Controller should rotate or not ?".
For example :
- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
// Get the new screen width
self.cellWidth = self.view.frame.size.width;
// Recalculate the view
[self rebuildTheView];
}
In most of the cases, implementing shouldAutorotate in all your ViewController is sufficient if you set the right resize settings in Interface Builder. Check that you did that before implementing didRotateFromInterfaceOrientation or willAnimateRotationToInterfaceOrientation
For example :
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return [ViewToolkit orientationIsSupported:interfaceOrientation];
}

iPhone screen rotates at random ?

I use a tabBar Controller as root controller. It has 4 tabs and each of its ViewControllers has
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation {
return YES;
}
as well as the tabBarController itself.
But when I rotate the device (real or simulator), the screen turns at random! If it doesn't turn when I open the application it would have the same behavior until I quit the app.
I tried to add the 4 viewControllers one by one in IB to see if one was problematic, but I obtained the same issue. It only always turns when there is no tabs at all!
Please tell me if you have any ideas. Thanks!
You set every view controller to say that it responds to any possible orientation. Therefore, every view will attempt to rotate to every orientation.
Views don't really automatically rotate. You usually have to manage the placement of subview programmatically in all but the simplest views.
If you have no custom orientation code, you're probably seeing the views try to draw the portrait view in the landscape frame or vice versa. If you have autoresize subviews set your subviews will appear to scatter across the screen in a seemingly random pattern. The more you change orientation, the more random the placement becomes.
For complex views, I like to create separate viewController/view pairs for each orientation. Then I put the views in a nav controller. As the orientation changes, each view controller will push or pop the appropriate view controller for the coming orientation onto/off the stack. To the user, this looks like a single view is gracefully redrawing itself. (This is especially useful if you have non-standard UI elements that have to be manually rotated with transforms)
You have to subclass UITabBarController and implement shouldAutorotateToInterfaceOrientation:
Actually, I just want my first tab view controller to rotate. So I put this code in my custom tabBarController :
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation {
if (self.selectedIndex == 0) {
return toInterfaceOrientation != UIInterfaceOrientationPortraitUpsideDown;
}else {
return toInterfaceOrientation == UIInterfaceOrientationPortrait;
}
}
but I had the same problem. I use a custom orientation code for my first tab view controller when turning to landscape. Called with the following function in my custom tabBarcontroller:
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
if (toInterfaceOrientation == UIInterfaceOrientationPortrait) {
//rotation to Portrait
lastOrientation = toInterfaceOrientation;
[[UIApplication sharedApplication] setStatusBarHidden:NO animated:NO];
[self.selectedViewController willRotateToInterfaceOrientation:toInterfaceOrientation duration:duration];
}
else if (UIInterfaceOrientationIsLandscape(toInterfaceOrientation)) {
if (!UIInterfaceOrientationIsLandscape(lastOrientation)) {
//rotation to Landscape
[self.selectedViewController willRotateToInterfaceOrientation:toInterfaceOrientation duration:duration];
}
lastOrientation = toInterfaceOrientation;
}
}
I found that if you set the selected tab programmatically the tabViewController rotates erratically.