UITableView scrolling under the navigation bar - iphone

I have a table view setup which currently, when being flickered up, has its sections flush up against right underneath the status bar, instead of flushing against the the navigation bar. I'm not sure if this is the proper behavior, but most applications have the Section Title flush properly below the navigation bar when it's slid into view.
What's the right way to correct this instead of downsizing the tableView arbitrarily?
* EDIT *
Related to a thread I created in Broken cell with an odd strikethrough?. This problem plus the 'cell strike-through' problem occurs when I set my Navigation Bar to a Translucent Black. When it's Black Opaque or Normal, such a problem does not exist. I'm not sure if that's a result of something else in my code or an issue with the SDK.

Sounds like you either don't have the bounds set properly in IB, or your springs-and-struts aren't correct. Is this the top level of the UIViewController, or a subview? Are you using a UINavigationController? If you test the interface in IB, does it look okay?

I had a similar problem and it gets fixed automatically by setting this
self.navigationController.navigationBar.barStyle = UIBarStyleBlackTranslucent;

As I indicated in the other post, I suspect the hierarchy of views under the UINavigationController has become disrupted.
The layoutSubviews in the content view (which contains the navigation bar and your UITableView) of the UINavigationController should be sizing the UITableView such that it doesn't overlap the navigation bar. In your case, I'm guessing that either the UITableView is resizing itself afterwards or the layoutSubviews doesn't know about the UITableView for some reason and the UITableView is passing underneath the navigation bar, causing the alignment issue you are seeing.

I had the same problem on iOS 5.1 using the following code:
Create the navigation controller & add a table view
UINavigationController *navigationController = [[UINavigationController alloc] init];
[navigationController setModalPresentationStyle:UIModalPresentationFormSheet];
[navigationController setModalTransitionStyle:UIModalTransitionStyleFlipHorizontal];
[navigationController.navigationBar setBarStyle:UIBarStyleBlack];
[navigationController.navigationBar setTranslucent:TRUE];
[navigationController setNavigationBarHidden:NO animated:NO];
[self presentModalViewController:navigationController animated:YES];
MyTableViewController *aTableViewController = [[[MyTableViewController alloc] initWithStyle:UITableViewStylePlain] autorelease];
aTableViewController.navigationItem.rightBarButtonItem = buttonItem;
[navigationController pushViewController:aboutTableViewController animated:YES];
Add a Table Header View to the table
ATableHeaderView aTableHeaderView = [[[ATableHeaderView alloc] initWithFrame:aboutTableView.frame] autorelease];
[aTableHeaderView setAutoresizingMask:UIViewAutoresizingFlexibleHeight|UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleTopMargin];
[aTableHeaderView sizeToFit];
[aTableView setTableHeaderView:aTableHeaderView];
Inside the table header view I added some labels
UILabel *aLabel = [[[UILabel alloc] initWithFrame:CGRectMake(x,y, width, height)] autorelease];
[aLabel setText:aString];
[aLabel setAutoresizesSubviews:YES];
[aLabel setAutoresizingMask:UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth];
I ended up with the table header content under the navigation bar. Changing the navigation bar to solid black fixed it. But this is not what I wanted. After some trial and error I removed the line:
[aLabel setAutoresizingMask:UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth];
From the setup of the UILabel in the header and the problem is fixed. I have a translucent header and the content of the table is positioned properly.

Related

iPhone UINavigationBar

I'm using UINavigationController and I have a UIView added to self.window
UIView *myView = [[UIView alloc] init];
myView.frame=CGRectMake(0,20,320,100);//20 is to position view under status bar
[[[self.window subviews] objectAtIndex:0] addSubview:myView];
This is done in AppDelegate.m file.
And this way myView covers up the navigation bar completely.
However, when the screen orientation changes, somehow the navigation bar is brought to the very front (just like what bringSubViewToFront does) and is on top of myView (a portion of view is covered up by navigation bar).
Does anyone know why this happened? Is there a way I can keep myView on top of everything?
If you don't want to show the navigation bar, just hide it:
self.navigationController.navigationBarHidden = YES;
or:
[self.navigationController setNavigationBarHidden:YES animated:YES];
if you want to animate the change from not hidden to hidden.
You can also adjust the "z" coordinate for stuff on the screen
[aview sendSubviewToBack:asubview];
and
[aview sendSubviewToFront:asubview];

UIPopoverController and UINavigationController cuts corners

I have a problem with the display of my popover. After initWithContentViewController: and presentPopoverFromBarButtonItem:permittedArrowDirections:animated: it cuts corners of the navigation bar. How should I fix it?? Thanks.
This is the code I'm using
NavContr *nav = [NavContr new];
nav.navigationBar.backgroundColor = [UIColor redColor];
UIPopoverController *tempPop = [[UIPopoverController alloc] initWithContentViewController:nav];
[tempPop presentPopoverFromBarButtonItem:mainButtonItem permittedArrowDirections:UIPopoverArrowDirectionUp animated:NO];
EDIT: I have resolved this problem:
+ (void)configure:(UINavigationController *)navController {
UINavigationBar *navigationBar = navController.navigationBar;
UIView *contentView = nil;
for (UIView *view in navController.view.subviews) {
if ([[NSString stringWithFormat:#"%#", [view class]] isEqualToString:#"UILayoutContainerView"])
contentView = view;
}
// setting frame to navigation bar and content view
[navigationBar setFrame:CGRectMake(navigationBar.frame.origin.x, 0, navigationBar.frame.size.width, navigationBar.frame.size.height)];
[contentView setFrame:CGRectMake(contentView.frame.origin.x, 0, contentView.frame.size.width, contentView.frame.size.height + navigationBar.frame.size.height)];
[navController.view bringSubviewToFront:contentView];
for (UIView *customView in contentView.subviews)
customView.frame = CGRectMake(customView.frame.origin.x, customView.frame.origin.y + navigationBar.frame.size.height, customView.frame.size.width, customView.frame.size.height);
[contentView addSubview:navigationBar];
[contentView bringSubviewToFront:navigationBar];
}
This is probably because you have no root view controller, or are otherwise fiddling with the navigation controller in ways it was not meant to be played with. This is how you ought to be setting up the popover:
MyCustomViewController *viewController = [[UIViewController alloc] initWithNibName:#"MyCustomViewController" bundle:nil]; //or storyboard or whatever
UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:viewController]; //you should have a root view controller before displaying the popover
tintColor = [UIColor redColor];
UIPopoverController *tempPop = [[UIPopoverController alloc] initWithContentViewController:nav];
[tempPop presentPopoverFromBarButtonItem:mainButtonItem permittedArrowDirections:UIPopoverArrowDirectionUp animated:NO];
There are a few very important things going on here:
Your navigation controller should have a root view controller before you display it.
This code is using a standard UINavigationController instance. According to the documentation, you should not subclass UINavigationController, nor should you try and reinvent the wheel. Apple has created a complex and comprehensive framework, UIKit, that you can use to build amazing apps. If you try and step outside the box, you'll be creating an awful lot of work for yourself without any appreciable benefit.
This is using the tintColor property of the UINavigationBar class. If the tint is insufficient for your UI, you can also set the background image manually (refer to the docs).
If you want to make a popover with a navigation controller, use the built-in UINavigationController class. Don't subclass it and don't reinvent it. To customize the appearance of the navigationBar, use the UI_APPEARANCE_SELECTOR methods in the UINavigationBar class.
I get the solution before add CALayer the UIPopOverController shows like
after adding below lines in table view class i get the following UIPopOverController
#import <QuartzCore/QuartzCore.h>
CALayer *imageLayer2 = self.tableView.layer;
[imageLayer2 setCornerRadius:-20];
[imageLayer2 setBorderWidth:1];
Try it in your project may be it works!!
Thanx
I have tried & replicate the issue you are facing, made some R&D. It's due to the line of code below :
nav.navigationBar.backgroundColor = [UIColor redColor];
While you set the background color of the navigation bar it will behave weird due the native shape of the pop up. Try and remove the below line, you will definitely have issue resolved.
If you are specifying the Rect where the popover appears, we've found that using decimals can result in weird distortions like that. Be sure you're using whole number for origin and size.

addSubView to viewController.navigatorController

I have a viewController and I am trying to add a subview to it such that it will cover the whole screen, however this has a navigationController in it so that adding a subView always adds it below the navigation bar, is there a way to simulate a presentModalViewController in cases like this?
You can add the subview to the view controller and then hide the navigation controller from the top or you could still push it to the navigation controller and then just remove the navigation controller from the top again and then you could use pop to go back and forth.
the code to push a view controller is
if(!self.YOURVIEWCONTROLLER){
self.YOURVIEWCONTROLLER = [[YOURVIEWCONTROLLER alloc] initWithNibName:#"YOURVIEWCONTROLLER" bundle:nil] autorelease];
}
[self.navigationController pushViewController:self.YOURVIEWCONTROLLER animatedLYES];
and on the next NEXTView.m add
[self.navigationController setNavigationBarHidden:YES];
remember to create an instance of YOURVIEWCONTROLLER in the .h file. Or you could do a simple
[self.view addSubview:NEWVIEW];
[self.navigationController setNavigationBarHidden:YES];
at least at bear minimum the line for making the navigationController hide is there.
I seem to recall once having a similar problem, and I seem to recall the solution was to add the subview to the navigation controller (as the view controller is already a sub view of the navigation controller) rather than adding it to the view controller.
I recently have similar problems and after spending 5 to 10 min I get the exact solution...
According to my solution I simply add my custom UIView to subview of navigationController.view
Like This :-
[self.navigationController.view addSubview:popOver];
popOver - Your custom UIView
Happy Codding :)
Add the view to the superview of the navigationController's view.
[navigationController.view.superview addSubview:viewController.view];
Perhaps you could hide the navigation bar when you add the subview. I have a method on my ViewController that looks like this:
self.navigationController.navigationBarHidden = YES;
UIView *v = [[UIView alloc] initWithFrame:self.view.frame];
v.backgroundColor = [UIColor redColor];
[self.view addSubview:v];
When that code executes, my navigation bar disappears and a full screen red view replaces it.

Custom UITabBarController Problems with View Controllers and Views

I'm writing a custom UITabBarController so I can fully control appearance of the tab bar. I've got it all working so I have an array of view controllers that it handles.
The controller has a main view which fills the screen, and inside it it has a UIView at the bottom for the tab bar. That tab bar view has a button for each view controller. When buttons are pressed I add the view controller's view to the main view, and set it's frame so that it doesn't cover the tab bar view:
controller.view.frame = CGRectMake(0, 0, self.view.bounds.size.width, self.view.bounds.size.height - kTabBarHeight);
This all works fine, and I can flick between the view controllers just fine. However, when I present a modal view controller, and then dismiss it, the current view controller's view becomes full screen and covers up my tab bar! I've tried setting the autoresizing masks to not resize, but is keeps happening.
I have also tried adding the view controllers view's to the bottom (below the tab bar) by using:
[self.view insertSubview:controller.view atIndex:0];
But when I do that, the tab bar is even visible above any modal views! Which is strange. I think there's something I'm not understanding so I would be grateful if someone can explain what I'm missing!
Thanks,
Mike
Try setting
controller.view.frame = CGRectMake(0, 0, self.view.bounds.size.width, self.view.bounds.size.height - kTabBarHeight);
in the controller's viewWillAppear method
Try this out. I think you want dynamic view controllers within tab bar controller.
-(void)applicationDidFinishLaunching:(UIApplication *)application {
// Add the tab bar controller's current view as a subview of the window
tabBarController.delegate=self;
tabBarController=[[UITabBarController alloc] init];
mainDashBoard=[[DashBoard alloc] initWithNibName:#"DashBoard" bundle:nil];
mainSearchView=[[SearchView alloc] initWithNibName:#"SearchView" bundle:nil];
mainMoreView=[[MoreView alloc] initWithNibName:#"MoreView" bundle:nil];
UINavigationController *nvCtr0=[[[UINavigationController alloc] init] autorelease];
UINavigationController *nvCtr1=[[[UINavigationController alloc] initWithRootViewController:mainDashBoard] autorelease];
UINavigationController *nvCtr2=[[[UINavigationController alloc] initWithRootViewController:mainSearchView] autorelease];
UINavigationController *nvCtr3=[[[UINavigationController alloc] initWithRootViewController:mainMoreView] autorelease];
UINavigationController *nvCtr4=[[[UINavigationController alloc] init] autorelease];//[[[UINavigationController alloc] initWithRootViewController:nil] autorelease];
tabBarController.viewControllers=[NSArray arrayWithObjects:nvCtr0,nvCtr1,nvCtr2,nvCtr3,nvCtr4,nil];
nvCtr0.tabBarItem.enabled=NO;
nvCtr4.tabBarItem.enabled=NO;
[window tabBarController.view];
}
I've managed to find a better way to control the appearance of the tab bar by simply inserting subviews to the top of the tab controllers tab bar. It's worked a treat!

iPhone: Weird space at the top of UINavigationController

I'm having a strange problem with adding a UINavigationController to my iPhone application. I add the controller as follows:
myViewController *viewController = [[myViewController alloc] initWithNibName:#"myView" bundle:nil];
myNavigationViewController *navigationController = [[myNavigationViewController alloc] initWithRootViewController:viewController];
UIView *finalView = myeNavigationViewController.view;
[self.view addSubview:finalView];
All seems to work as planned except I get a weird white space at the top of my view between the status bar and the UINavigationController title bar.
alt text http://www.andrewskinner.name/problem.png
I've searched online but don't really know what to search for. Has anyone else had this problem? Can you point me in the direction of some help?
Thanks in advance.
What does the line
UIView *finalView = myeNavigationViewController.view;
add to the code? It's redundant as you can add the view directly without assigning it to a UIView first - plus it's incorrect as it references the myNavigationController and not navigationController..
I tend to do this
myViewController *viewController = [[myViewController alloc] initWithNibName:#"myView" bundle:nil];
myNavigationViewController *navigationController = [[myNavigationViewController alloc] initWithRootViewController:viewController];
[navigationController.view setFrame: [self.view bounds]];
navigationController.delegate = self;
[self.view addSubview:[navigationController view]];
Setting the frame to the bounds also removes the white space at the top you were asking about.
Check out the answers in this question:
Not sure why UIView is being nudged up by around 10px
The issue is that UINavigationController ideally should be the direct subView of UIWindow. It will position and size right by itself. When you add UINavigationController into another custom view of a UIWindow subview, you need to take care of the position and size of this custom view by taking into account whether the status bar is shown or not in the UIWindow.
My suggestion is to make the custom view as a subclass of UINavigationController:
mySubClass_NavigationController*nav=[[mySubClass_NavigationController alloc] initWithRootViewController:viewController ];
[myUIWindow addSubview:nav.view];
and inside the mySubClass_NavigationController, you can do all the customization that you are doing now in your self (whatever that controller is).
I struggled with this for a while too using very similar code to the op's and also had a white bar above my navigation controller.
My problem occurred when adding the UINavigationController as a view in a UITabController. The space in my case was caused by the UINavigationBar part of the UINavigationController taking into account the status bar and it was actually overlapping part of the view that I was trying to show in the UINavigationController.
This is the code I ended up with in loadView in one of my UITabBarController view controllers.
SomeUITableViewController *screenList = [[SomeUITableViewController alloc] init];
UINavigationController *navController = [[UINavigationController alloc]
initWithRootViewController:screenList];
CGRect frame = [[navController navigationBar] frame];
frame.origin.y = 0; // Was 20, set to 0 to not take into account the status bar.
[[navController navigationBar] setFrame:frame];
[self setView:[navController view]];
There's some more information at http://discussions.apple.com/message.jspa?messageID=7890362.
There is an obscure property in IB called "Hides Bottom Bar on Push". Just check it. It solved the problem for me.
Maybe you have somehow gotten yourself two UIViews,
each with a status bar. Check the xib.