1. Welcome to the new MacRumors forums. See our announcement and read our FAQ

A UIToolbar at the same time as a UINavigationController with a UITableView

Discussion in 'iPhone/iPad Programming' started by vegashacker, Jun 18, 2008.

  1. macrumors newbie

    Has anyone had success with this? I see the TheElements sample code, and it is close, but it uses a UITabBar, which, it turns out, is pretty different from the toolbar. I've tried all sorts of things (IB solutions, programmatic solutions, hybrid approaches), but I can't seem to get it. The most common system is that the table view covers up the toolbar.
  2. macrumors 65816


    Are you adding the toolbar on top of the table view? You can either just make sure to do [myView addSubview:myToolbar] after [myView addSubview:myTableView] which will add the toolbar layer on top of the table view, or you can ensure that its on top with something like [myView insertSubview:myToolbar aboveSubview:myTableView] to replace the toolbar addSubview.

    Could be that the table view is simply higher in the view hierarchy than the toolbar due to the way you implemented it, so its getting covered up.
  3. macrumors newbie

    Thanks! I've at least got it working now with a stripped-down version. I did it all programmatically. I created my navigation controller (which houses the table view), added it as a subview, and then added a toolbar as a subview. And it all seems to work (at least this very basic version). I'm thinking what happenened was maybe because I did the toolbar in Interface Builder, it was getting either covered up, or somehow totally covering the nav+table view, depending on the order I did stuff. (This doesn't totally make sense to me, but the programmatic solution is good enough!) At any rate, your post totally helped. Thanks a bunch,

  4. macrumors newbie

    I had the same problem. I ended up having to add the toolbar to the window in the AppDelegate, same place I added the navigation controller. But I'm a little uncertain if that's the best place because as I pass from controller to controller, I'll be showing a different set of toolbar items or maybe no toolbar at all.

    As I understand it, attaching it to the window means that it's there and each controller will have to act on it manually. What I'd like is each controller to make its own toolbar so that they change as a matter of course when switching between them.

    Am I missing something? (Which is quite likely since I'm new to Cocoa and especially Cocoa Touch.)

  5. macrumors 65816


    There should be no reason you need to add the toolbar to the window rather than the view that is being controlled by each view controller.

    I don't really get what you're asking here. Just create a toolbar for each controller's view and set it up there.
  6. macrumors newbie

    It turned out that addSubview was working just fine. I just had my frame all wrong so it was appearing after the tableview portion. It didn't make sense to you because it didn't make sense to me either--I just didn't scroll looking for it.

  7. macrumors newbie

    I figured out what I wasn't getting. I was adding the toolbar to the window so that it would stay in place as the UITableView was scrolled. By adding it as a subview of the UITableView, the toolbar is just tacked on to the bottom and scrolling moves it as well.

    So my initial thought on how to address that was to adjust the frame of the UITableView to accommodate the toolbar but that had no effect. All I'm looking for is a navigation bar at the top, a fixed toolbar at the bottom, and a table view in between. Adding the toolbar to the window is the only way I've found to accomplish the fixed part but it's awful conceptually.

    I know I'm missing something. Any ideas?

    Thanks so much,

  8. macrumors 65816


    Add the toolbar to the UIViewController's view (the one that's currently at the top of the navigation stack) that you added the UITableView to, not the toolbar to the UITableView itself.

    I can't see why you'd want to add the toolbar to the window's view or to the table view. Add it to whatever view the table view is in.
  9. macrumors newbie

    I set up the NavigationController like so:

    MyTableViewController *rootViewController = [[MyTableViewController alloc] initWithStyle:UITableViewStylePlain];
    navController = [[UINavigationController alloc] initWithRootViewController:rootViewController];
    [rootViewController release];
    [window addSubview:[navController view]];
    That's why I was trying to add it to the window or the table view. In MyTableViewController, I add the toolbar in on the initWithStyle call:

    - (id)initWithStyle:(UITableViewStyle)style
    	appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
    	if (self = [super initWithStyle:style])
    		NSString *title = [[appDelegate myItem] title];
    		[self setTitle: title];
    		[[[self navigationItem] backBarButtonItem] setTitle: title];
    		toolbar = [UIToolbar new];
    		[toolbar sizeToFit];
    		CGFloat toolbarHeight = [toolbar frame].size.height;
    		CGRect mainViewBounds = [[UIScreen mainScreen] applicationFrame];
    		[toolbar setFrame:CGRectMake(CGRectGetMinX(mainViewBounds), CGRectGetMinY(mainViewBounds) + CGRectGetHeight(mainViewBounds) - 108.0, CGRectGetWidth(mainViewBounds), toolbarHeight)];
    		[self createToolbarItems];
    		[self.view addSubview:toolbar];
    	return self;
    That's all the relevant code. Currently, the toolbar is attached to the table view such that it scrolls along with it. I tried getting a reference to the NavigationController and then adding it to its view and a bunch of other routes.

    I'm sorry to be such a pain about this: I've come a long way using the supplied example apps to learn how to program the iPhone but there's very little out there about UIToolbar. Only UICatalog makes use of it. So I very much appreciate your patience with me.

  10. macrumors newbie

    A solution!

    I spent a lot of time trying to figure out how to get my toolbar to be fixed on the bottom of the screen. I had a UITableViewController which had a UINavigationBar, as well as its inherent tableView. The key was to use the parentViewController property of self, instead of using the current view. Here is my code:

    UIToolbar *toolbar = [UIToolbar new];
    toolbar.barStyle = UIBarStyleDefault;
    [toolbar sizeToFit];
    //Set the frame
    CGFloat toolbarHeight = [toolbar frame].size.height;
    CGRect mainViewBounds = self.parentViewController.view.bounds;
    [toolbar setFrame:CGRectMake(CGRectGetMinX(mainViewBounds), CGRectGetMinY(mainViewBounds) + CGRectGetHeight(mainViewBounds) - toolbarHeight, CGRectGetWidth(mainViewBounds),toolbarHeight)];
    //Here we go
    [self.parentViewController.view addSubview:toolbar];
    Enjoy :)
  11. macrumors newbie

    I tried that and it didn't work. I think the reason is that I had the root view of the window tied to the UINavigationController instead of the UITableViewController. In my way, the subview of the UINavigationController was the UITableViewController and not the other way around. I think that's the way it was done in one of the sample applications.

    I'll just have to retool things a bit. Thanks for the help!

  12. macrumors member

    I had this problem also. I started with the Navbar sample, and ran into troubles adding a UIToolbar to the view, underneath the table view. My problem was that the toolbar seemed to want to draw itself at the top of the frame. I had to explicitly set the frame as below to draw it in the right place:

    	UIView* v = [navigationController view];
    	[window addSubview:v];
    	[v addSubview:toolbarView];
    	CGRect rectToolbar = toolbarView.frame;
    	CGRect rectSuperview = v.bounds;
    	rectToolbar.origin.y = rectSuperview.size.height - toolbarView.frame.size.height;
    	toolbarView.frame = rectToolbar;
    	[window makeKeyAndVisible];
  13. macrumors member

    UIToolbar on a UITableViewController on a UINavigationController?

    I have a UINavigationController. I add UITableViewController to it (different ones at different times, depending on where we are in the app).

    Now I want a toolbar added to it.

    If I add it to the parentViewController.view, then the tableView thinks it extends to the bottom of the window and the last row is masked by the toolbar.

    If I add it to the view in the UITableViewController, it appears in the right place---until I scroll the list. Then the toolbar scrolls with it! Not a good look for an app.

    Any ideas where to attach my toolbar to keep it fixed in place on my UITableViewController, which is on a UINavigationController?
  14. Moderator


    Staff Member

    I simply placed the toolbar where I wanted it (in code) and made the table view smaller by the height of the toolbar.

    Attached Files:

  15. macrumors member


    I thought of that, but it doesn't appear that I can change the frame on the UITableView in a UITableViewController. It ignores my attempts to do so and fills the frame any way.

    Do I have to abandon the UITableViewController and just stick a UITableView on a UIViewController to get this to work right, do you think?

  16. Moderator


    Staff Member

    Possibly. All I can say for sure is that mine is a UIViewController subclass.
  17. macrumors member


    This seems like cheating---but the framework has so far withstood my efforts to do it the "right" way. ;)

    I just set the self.tableView.tableFooterView to a new UIView with a height of (toolbar height + 5) and it looks great!


    I'm going with that.
  18. Moderator


    Staff Member

    Seems fine to me. Could you not have set it to a UIToolbar though? It is a UIView...
  19. macrumors member

    UIToolbar as footer

    I think then the toolbar would have been a child of the table, and would have scrolled with the table as it scrolled. Again, I don't have a fixed-height table, here. As you add items to a list, it will exceed the size of the screen and have to be scrolled.
  20. macrumors regular

    Hey Robbie, could you post your code for that or at least an example that does what is in the picture? I'd really like to see it, thanks.
  21. Moderator


    Staff Member

    Well, I intend selling this app to try and hopefully get some of the fee for distributing apps back, but I don't see that this part of the code is in any way special!

    The basic structure of the UI is that I have a UITabBarController created in the app delegate when the application starts (in code, I have no xibs or nibs). I then add two UINavigationController objects to it (via the viewControllers property).

    When the user selects one of the stations presented in the tables that the navigation controllers display I push a view for that station. It's that final "leaf" view that the screenshot is of. So we have already have the tab and navigation views on screen.

    This is the (simplified) code for loadView in that final UIViewControllerSubclass

    - (void) loadView
    // Set the size for the table view
    CGRect tableViewRect;
    tableViewRect.size.width = [[UIScreen mainScreen] applicationFrame].size.width;
    tableViewRect.size.height = [[UIScreen mainScreen] applicationFrame].size.height-27;
    tableViewRect.origin.x = 0;
    tableViewRect.origin.y = 0;
    // Create a table viiew
    tableView = [[UITableView alloc] initWithFrame:tableViewRect				style:UITableViewStylePlain];
    // set the autoresizing mask so that the table will always fill the view
    tableView.autoresizingMask = (UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight);
    // set the tableview delegate to this object
    tableView.delegate = self;	
    // Set the table view datasource to the data source
    tableView.dataSource = self;
    // Set the size and position for the "status" bar.  This is actually a UIToolbar as we have clickable buttons on this	
    CGRect statusRect;
    statusRect.size.width = [[UIScreen mainScreen] applicationFrame].size.width;
    statusRect.size.height = 28; // Not this height is hard coded
    statusRect.origin.x = 0;
    statusRect.origin.y = [[UIScreen mainScreen] applicationFrame].size.height-120; // Note that 120 is hard coded: would be better to find the height to subtract from the existing views
    // Create the status bar/toolbar	
    statusView = [[UIToolbar alloc] initWithFrame:statusRect];
    // Status items creation/sizing skipped		
    statusView.items = idleItems; // Idle items is an array of items to display when download not in progress
    // This view contains the table view and the status bar
    UIView *totalView = [[UIView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]];
    [totalView addSubview:tableView];
    [totalView addSubview:statusView];
    self.view = totalView;
    [tableView release]; // Don't leak memory!
    So there we go: it's pretty simple and straight forward. As noted it would be better to read the heights from the tab and navigation bars, but this does work :)

    Hope that helps...
  22. macrumors regular

    Thanks man, I appreciate it.
  23. macrumors newbie

    What does your code look like (if I can ask?). I'm trying to mod SeismicXML's table/navigationController view to add a toolbar at the bottom. I can declare the toolbar, but that's about it.

  24. macrumors newbie

    very helpful tips how to add tableview presizely in your mainview

    Manny many thanks to you.

    this is very helpful in add multiple view in a same window.

    thanks a lot.
  25. polarbear128, Jan 10, 2011
    Last edited by a moderator: Jan 10, 2011

    macrumors newbie

    Thank you for this...it fixed a weird bug I (and maybe everyone) had - a view with two subviews, UIToolbar at the top and UITableView underneath it.
    In the simulator, the toolbar would stay static when scrolling the table view up and down.
    On the iphone, the same thing would happen until the top cell was reached when scrolling down, and then the toolbar would follow the top of the table down.
    Most odd.

    I was adding the two subviews directly to the controllers view, as in:

    [self.view addSubview:toolbar];
    [self.view addSubview:tableview];
    On a hunch, I tried your method...creating an intermediate UIView, adding the subviews to that, and then assigning that view to the current controllers view. It works!

    Not sure why the difference, but it appears to have appeased the xcode gods.

Share This Page