Please do not post the same thing multiple times. The board software automatically flags certain posts as needing moderator attention. This happens the most often for new users. I'm pretty sure this is made clear at the time you attempt to post. Posting the same thing over and over again just makes that many more posts the moderators have to weed through later. This makes us sad. Don't make us sad. If your post/thread doesn't appear, just wait a while. Don't post it again. If it hasn't shown up by the next day, then you can try again. I normally go through posts in the mornings, and try to check a few times throughout the day, but I'm not here 24/7. There will typically be a significant delay before posts are approved. Just be patient.
Tab Bar Controller - Navigation Controller - TableView
I am having a bear of a time getting this to work. I've looked at it so many ways and followed tutorials on how to set each of the controllers separately but none show how to combine them all.
super simple bare bones sample
- create new Tab Bar Application - create a new FirstScreenViewController .h and .m class - add the appropriate TableView methods (as explained in other articles) - Create a new FirstScreen.xib with a UIView - Drop a TableView onto the View - set the files owner to point to FirstScreenViewController - Save to project - load up MainWindow.xib - set the first tab to be a Navigation Controller - set the first tabs xib to point to the FirstScreen.xib file
Save and run. I see a TabBar window with two buttons. the first button has a navigation controller toolbar up top and i can see the outlines of an empty Table View. Looks great so far.
Load up my FirstScreenViewController.xib file. Connect the view, tableview datasource and tableview delegate to point over to the Files Owner. Save
Run the project, hangs for a second then dumps me back to xcdoe with an unhandled error. Take out the datasource and delegate connections and i'm back to see a blank tableview.
Any Ideas? I know this is a long winded desription.. sorry. I'm able to create a single page application with a tableview with no problem but when i dump this into a tabbar controller it craps out.
Have you pushed the tableview onto the navigation controller's stack?
you might try setting the tableViewControllers' delegates and datasources programatically just in case you're unintetionally doing something weird in interface builder.
I've done all of my development programatically so far, because I like to see things explicitly spelled out, not hidden behind a gui the way they are in IB.
I will contact you in private with a template and some help. I found the same issue and a complete and easy way around it.
Thanks DevTeam. I received your PM. If you have an outline of what i should do to simplify this even more please post in the thread so others who might be having the same problem can learn from your suggestions as well!
The issue is actually fixed by forgetting about a TabBarController application. Do everytihng on a basic application basis.
Create your tab bar controller programatically, and your navigationcontroller programmatically too.
then create a UITableViewController and add that to the NavController created in the App Delegate. Add that NavController to the Tab Bar Controller. Add the Tab Bar Controller's view to the window.
Do everything in the App Delegate to do with TabBarControllers and Navigation Controllers. They are simple and easy to make programatically, so why on earth muddle it up with Interface Builder. The fact is, that the templates provided in Xcode have never been the simplest. They have actually been pathetically convoluted. Just create a navigation controller and tab bar controller, add the view Controller to the nav controller, and add the nav controller to the tab bar controller.
I use Interface builder sparingly. It often makes things far more complicated. This is one example of it. NavControllers and TabBarControllers should NEVER be made via interface builder, but by code. Apple never uses interface builder for this, as its way too stupidly set up. The programing way to do it is simpler, and far more understandable when you understand a bit of Objective-C.
tabBarController = [[UITabBarController alloc] init]; // creates your tab bar so you can add everything else to it
myTableViewController = [[MyTableViewController alloc] init]; // creates your table view - this should be a UIViewController with a table view in it, or UITableViewController UINavigationController *tableNavController = [[[UINavigationController alloc] initWithRootViewController:myTableViewController] autorelease]; [myTableViewController release]; // creates your table view's navigation controller, then adds the view controller you made. Note I then let go of the view controller as the navigation controller now holds onto it for me. This saves memory.
mySecondTableViewController = [[MySecondTableViewController alloc] init]; UINavigationController *table2NavController = [[[UINavigationController alloc] initWithRootViewController:mySecondTableViewController] autorelease]; [mySecondTableViewController release]; // does exactly the same as the first round, but for your second tab at the bottom of the bar.
tabBarController.viewControllers = [NSArray arrayWithObjects:tableNavController, table2NavController, nil]; add both of your navigation controllers to the tab bar. You can put as many controllers on as you like, but they will turn into the more button like in the iPod program.
[window addSubview:tabBarController.view]; // adds the tab bar's view property to the window [window makeKeyAndVisible]; // makes the window visible }
- (void)dealloc { [tabBarController release]; [window release]; [super dealloc]; } // lets go of everything else, thats so your program doesn't create any leaks of memory.
I just typed up this quick App Delegate to show you how to do it. Yes, you do have rights to use whatever part of it you wish, and yes, you can ask any questions you like.
Please do note: a ) I release the table views because they have been retained by the Navigation Controllers. Thus, I have doubled up and am taking double the memory. Once you have a nav controller holding your view, drop it. This saves memory. These nav controllers are set to drop automattically with their autorelease so there is no leak issue.
b ) if you need to add only one item to your tabBar for some strange reason, or just to test, change "arrayWithObjects: blah, blah2, nil" to "arrayWithObject: blah" and drop the nil. :)
Thanks Dev. I was able to get that code running with one tab showing a UINavigationController and a table full of data and the other tab showing a UIViewController with a page of labels and buttons. Very nice.. thank you!
I am hitting a wall though. Using your code i've tried any number of ways to add content below the nav bar but above the tableview. I'm trying to get the following look for this app....
Pseudo Description: - App should have a tabbar at the bottom with two tabs - the first tab shows a navigationcontroller up top, label and image below it followed by a tableview. - the second tab shows labels and images.
For whatever reason the tabbar is the big pain! I know this isnt rocket science.. it's just not clicking. I can perform these tasks w/out the tab bar but throw that into the mix and i'm getting nothing but a white page on that first tab.
A UINavigationController can hold any type of UIViewController. If its subclassed under the UIViewController type, a NavigationController can hold it. Just remember though, that without scrolling capabilities, and with your tab bar, you need to accomodate that in your viewcontroller, and not put anything more than a nagivationbar AND a tab bar's away from the bottom. Just be careful there :)
There are several options I can think of with your little issue there.
One is to add what you are trying to do as a header to the TableView. Check out the TableViewProgramming guide and you will learn you can put a header over the top, and a footer underneath, the table view you are working on. You can also do section headers too.
The other option, and one I have never tried, (and don't really want too as I feel it has a 50/50 chance of not working ) is to try adding a UITableView to a viewController, and fixing that viewController up correctly. I don't know if this will work, but you would then need to add that UIViewController (an instance of it anyway) to your tab bar.
Something I forgot to mention before. Remember that the name on your tab bar and in the navigation controller is set by this code in the first viewController or TableViewController you add to the navigation bar:
good idea regarding the tableview header. i'll have to check it out but my initial thought is it might not work for me as i dont want that header (with the image and labels) scrolling up and off the screen when the user scrolls the table down. I want the label and picture to be fixed at a position above the table. That might be the gotcha.
I'll play around with the header though.. maybe there's a fixed-to-view property or something like that..
UINavigationController is a very strict class, btw. You seem to be playing around with it from what you were saying, though you were a bit difficult to follow at the end.
Simply add whatever view you want into the NavigationController via the initWithRootViewController method.
Also make sure that you always create the navigationController IN THE APP DELEGATE!!!!! That Is SOOO important. I have seen a few apps on App Store with the stupid error of subclassing UINavigationController in another place other than the app delegate.
Never play around with NavigationController by subclassing it. There is NO reason to, and it creates an error as the navigationController compensates for the status bar at the top of the view. This leaves a big black hole wherever it was subclassed.
Points to take away:
NEVER subclass UINavigationControllers. (same also applies with UITabBarControllers] Just add whatever ViewController you want via the initWithRootViewController: method
Check out the View Controller Programming Guide for more ideas of what to do with navigationControllers.
good idea regarding the tableview header. i'll have to check it out but my initial thought is it might not work for me as i dont want that header (with the image and labels) scrolling up and off the screen when the user scrolls the table down. I want the label and picture to be fixed at a position above the table. That might be the gotcha.
I'll play around with the header though.. maybe there's a fixed-to-view property or something like that..
Thanks again John
I don't believe there is one of those.
Perhaps add a tableView as i said...
Still have a play. :) also, don't overstep your bounds. Theres some things which simply aren't possible. Know when to quit, and alter your ideas according to the restrictions.
Oooh... just had an idea... you can create tableViews without TableViewControllers. Just set your viewController as the delegate and datasource and it shouldn't be an issue.
Then you could add the tableView as a subview (as you can change it in interface builder if you want to...) and then add the section as a fixed section also by the same UIViewController
Oooh... just had an idea... you can create tableViews without TableViewControllers. Just set your viewController as the delegate and datasource and it shouldn't be an issue.
Then you could add the tableView as a subview (as you can change it in interface builder if you want to...) and then add the section as a fixed section also by the same UIViewController
Not sure i completely follow you on this one. I'll have to sit on the idea for a while so that i can focus on the rest of the app.. maybe it'll make sense to me later on. I know it's something simple.
This can't be as difficult as i'm making it... - App should have a tabbar at the bottom with two tabs - the first tab shows a navigationcontroller up top, label and image below it followed by a tableview. - the second tab shows labels and images.
Thanks for all your help.. i picked up a few things going down this rabbit hole. John
It was quite simple. In your first tab, create a UIViewController that is controlled by the UINavigationController. In that view Controller, place the label and the image at the top, then put in your tableview below it. You don't need a tableViewController to create a table view. your UIViewController can act as your controller for the table view.
You don't technically need to release listTableView until dealloc. Move your release of listTableView to there and try. I had this error a few times. It's just released there for memory management.
You don't technically need to release listTableView until dealloc. Move your release of listTableView to there and try. I had this error a few times. It's just released there for memory management.
Try it there and let us know how u go.
Yeah I tried that and it didnt work. Here is my h file....am I missing something?
To mitigate this, add the following two lines: listTableViewController = [[ListTableViewController alloc] init]; myInfoTableViewController = [[MyInfoTableViewController alloc] init];
also move your releases back to the positions you had them, straight after you added each of the viewcontrollers to their respective navigation controllers.
add the lines i mentioned before you create each of those navigation controllers. Add the myInfo one after the release of listTableViewController, to save on memory. Loading lazily and releasing early is good practice for apps that may become very high in memory usage.
This is a great thread for getting started with tab-bar setup. Quick dumb question, though. In my sample app, I have 2 tabs, the first one is pointing to a UINavigationViewController class, and the other is pointing to a regular ViewController class. It's working great, and it's allowing me to add navigation buttons, etc, to the first tab using the above-mentioned example code, but what I want is to have a TableViewController in the Navigation window (tab #1), in order to contain a list for selection within the Navigation. Or if there is a better way to do this, please let me know (I'm quite new to this).
How can this be easily accomplished via the code? I really want to avoid using IB in any of this part of my test app, and I can't find many examples of creating this without IB out there..
Replies
you might try setting the tableViewControllers' delegates and datasources programatically just in case you're unintetionally doing something weird in interface builder.
I've done all of my development programatically so far, because I like to see things explicitly spelled out, not hidden behind a gui the way they are in IB.
Good luck!
Charlie
- Spam
- Abuse
- Troll
0 • Off Topic Insightful Disagree Dislike Like Awesome- Spam
- Abuse
- Troll
0 • Off Topic Insightful Disagree Dislike Like AwesomeThanks a million!
John
I love being a dad, flying airplanes and writing code.
----------------------------------------------------------------------
Follow me on Twitter: <a href=
- Spam
- Abuse
- Troll
0 • Off Topic Insightful Disagree Dislike Like AwesomeCreate your tab bar controller programatically, and your navigationcontroller programmatically too.
then create a UITableViewController and add that to the NavController created in the App Delegate. Add that NavController to the Tab Bar Controller. Add the Tab Bar Controller's view to the window.
Do everything in the App Delegate to do with TabBarControllers and Navigation Controllers. They are simple and easy to make programatically, so why on earth muddle it up with Interface Builder. The fact is, that the templates provided in Xcode have never been the simplest. They have actually been pathetically convoluted. Just create a navigation controller and tab bar controller, add the view Controller to the nav controller, and add the nav controller to the tab bar controller.
I use Interface builder sparingly. It often makes things far more complicated. This is one example of it. NavControllers and TabBarControllers should NEVER be made via interface builder, but by code. Apple never uses interface builder for this, as its way too stupidly set up. The programing way to do it is simpler, and far more understandable when you understand a bit of Objective-C.
- Spam
- Abuse
- Troll
0 • Off Topic Insightful Disagree Dislike Like Awesome- Spam
- Abuse
- Troll
0 • Off Topic Insightful Disagree Dislike Like Awesome- John
I love being a dad, flying airplanes and writing code.
----------------------------------------------------------------------
Follow me on Twitter: <a href=
- Spam
- Abuse
- Troll
0 • Off Topic Insightful Disagree Dislike Like AwesomeI just typed up this quick App Delegate to show you how to do it. Yes, you do have rights to use whatever part of it you wish, and yes, you can ask any questions you like.
Please do note:
a ) I release the table views because they have been retained by the Navigation Controllers. Thus, I have doubled up and am taking double the memory. Once you have a nav controller holding your view, drop it. This saves memory. These nav controllers are set to drop automattically with their autorelease so there is no leak issue.
b ) if you need to add only one item to your tabBar for some strange reason, or just to test, change "arrayWithObjects: blah, blah2, nil" to "arrayWithObject: blah" and drop the nil. :)
Does this help you???
- Spam
- Abuse
- Troll
0 • Off Topic Insightful Disagree Dislike Like AwesomeI am hitting a wall though. Using your code i've tried any number of ways to add content below the nav bar but above the tableview. I'm trying to get the following look for this app....
Pseudo Description:
- App should have a tabbar at the bottom with two tabs
- the first tab shows a navigationcontroller up top, label and image below it followed by a tableview.
- the second tab shows labels and images.
For whatever reason the tabbar is the big pain! I know this isnt rocket science.. it's just not clicking. I can perform these tasks w/out the tab bar but throw that into the mix and i'm getting nothing but a white page on that first tab.
Thanks Again
JB
Any thoughts? Thanks again for your help.
John
I love being a dad, flying airplanes and writing code.
----------------------------------------------------------------------
Follow me on Twitter: <a href=
- Spam
- Abuse
- Troll
0 • Off Topic Insightful Disagree Dislike Like AwesomeA UINavigationController can hold any type of UIViewController. If its subclassed under the UIViewController type, a NavigationController can hold it. Just remember though, that without scrolling capabilities, and with your tab bar, you need to accomodate that in your viewcontroller, and not put anything more than a nagivationbar AND a tab bar's away from the bottom. Just be careful there :)
There are several options I can think of with your little issue there.
One is to add what you are trying to do as a header to the TableView. Check out the TableViewProgramming guide and you will learn you can put a header over the top, and a footer underneath, the table view you are working on. You can also do section headers too.
The other option, and one I have never tried, (and don't really want too as I feel it has a 50/50 chance of not working ) is to try adding a UITableView to a viewController, and fixing that viewController up correctly. I don't know if this will work, but you would then need to add that UIViewController (an instance of it anyway) to your tab bar.
Something I forgot to mention before. Remember that the name on your tab bar and in the navigation controller is set by this code in the first viewController or TableViewController you add to the navigation bar:
And your tab bar image is set by:
BTW, do you see how easy it is to do it without IB? IB drives me nutty like this... and still people use it :s
- Spam
- Abuse
- Troll
0 • Off Topic Insightful Disagree Dislike Like AwesomeI'll play around with the header though.. maybe there's a fixed-to-view property or something like that..
Thanks again
John
I love being a dad, flying airplanes and writing code.
----------------------------------------------------------------------
Follow me on Twitter: <a href=
- Spam
- Abuse
- Troll
0 • Off Topic Insightful Disagree Dislike Like AwesomeSimply add whatever view you want into the NavigationController via the initWithRootViewController method.
Also make sure that you always create the navigationController IN THE APP DELEGATE!!!!! That Is SOOO important. I have seen a few apps on App Store with the stupid error of subclassing UINavigationController in another place other than the app delegate.
Never play around with NavigationController by subclassing it. There is NO reason to, and it creates an error as the navigationController compensates for the status bar at the top of the view. This leaves a big black hole wherever it was subclassed.
Points to take away:
NEVER subclass UINavigationControllers. (same also applies with UITabBarControllers]
Just add whatever ViewController you want via the initWithRootViewController: method
Check out the View Controller Programming Guide for more ideas of what to do with navigationControllers.
- Spam
- Abuse
- Troll
0 • Off Topic Insightful Disagree Dislike Like AwesomePerhaps add a tableView as i said...
Still have a play. :) also, don't overstep your bounds. Theres some things which simply aren't possible. Know when to quit, and alter your ideas according to the restrictions.
oh, well, enough commands from me :)
- Spam
- Abuse
- Troll
0 • Off Topic Insightful Disagree Dislike Like AwesomeThen you could add the tableView as a subview (as you can change it in interface builder if you want to...) and then add the section as a fixed section also by the same UIViewController
- Spam
- Abuse
- Troll
0 • Off Topic Insightful Disagree Dislike Like AwesomeThis can't be as difficult as i'm making it...
- App should have a tabbar at the bottom with two tabs
- the first tab shows a navigationcontroller up top, label and image below it followed by a tableview.
- the second tab shows labels and images.
Thanks for all your help.. i picked up a few things going down this rabbit hole.
John
I love being a dad, flying airplanes and writing code.
----------------------------------------------------------------------
Follow me on Twitter: <a href=
- Spam
- Abuse
- Troll
0 • Off Topic Insightful Disagree Dislike Like AwesomeYou don't need a tableViewController to create a table view. your UIViewController can act as your controller for the table view.
- Spam
- Abuse
- Troll
0 • Off Topic Insightful Disagree Dislike Like Awesome2008-08-16 16:39:45.134 AppTab[16817:20b] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[NSCFArray insertObject:atIndex:]: attempt to insert nil'
2008-08-16 16:39:45.136 AppTab[16817:20b] Stack: (
2454909259,
2496749819,
2454908715,
2454908778,
2465199056,
2464274948,
2464274708,
816674028,
816673653,
816663945,
10054,
816174362,
816210018,
2464512350,
2454412101,
2454412536,
829005112,
829005309,
816175835,
816221412,
9888,
9742
)
It seems to be failing on this line...
UINavigationController *tableNavController = [[[UINavigationController alloc] initWithRootViewController:listTableViewController] autorelease];
[listTableViewController release];
Ideas?
- Spam
- Abuse
- Troll
0 • Off Topic Insightful Disagree Dislike Like AwesomeTry it there and let us know how u go.
- Spam
- Abuse
- Troll
0 • Off Topic Insightful Disagree Dislike Like Awesome@class AppTabViewController;
@interface AppTabAppDelegate : NSObject {
UIWindow *window;
UIViewController *listTableViewController;
UIViewController *myInfoTableViewController;
}
@property (nonatomic, retain) UIWindow *window;
@property (nonatomic, retain) UIViewController *listTableViewController;
@property (nonatomic, retain) UIViewController *myInfoTableViewController;
@end
- Spam
- Abuse
- Troll
0 • Off Topic Insightful Disagree Dislike Like Awesome- Spam
- Abuse
- Troll
0 • Off Topic Insightful Disagree Dislike Like Awesome@implementation AppTabAppDelegate
@synthesize window, listTableViewController, myInfoTableViewController;
- (void)applicationDidFinishLaunching:(UIApplication *)application {
UITabBarController *tabBarController = [[UITabBarController alloc] init];
UINavigationController *tableNavController = [[[UINavigationController alloc] initWithRootViewController:listTableViewController] autorelease];
UINavigationController *table2NavController = [[[UINavigationController alloc] initWithRootViewController:myInfoTableViewController] autorelease];
tabBarController.viewControllers = [NSArray arrayWithObjects:tableNavController, table2NavController, nil];
[window addSubview:tabBarController.view];
[window makeKeyAndVisible];
}
- (void)dealloc {
[window release];
[listTableViewController release];
[myInfoTableViewController release];
[super release];
}
@end
- Spam
- Abuse
- Troll
0 • Off Topic Insightful Disagree Dislike Like AwesomeThe template I created was based upon those viewControllers being synthesized from an IBOutlet. Yours, however, are not.
- Spam
- Abuse
- Troll
0 • Off Topic Insightful Disagree Dislike Like AwesomelistTableViewController = [[ListTableViewController alloc] init];
myInfoTableViewController = [[MyInfoTableViewController alloc] init];
also move your releases back to the positions you had them, straight after you added each of the viewcontrollers to their respective navigation controllers.
add the lines i mentioned before you create each of those navigation controllers. Add the myInfo one after the release of listTableViewController, to save on memory. Loading lazily and releasing early is good practice for apps that may become very high in memory usage.
- Spam
- Abuse
- Troll
0 • Off Topic Insightful Disagree Dislike Like Awesome- Spam
- Abuse
- Troll
0 • Off Topic Insightful Disagree Dislike Like AwesomeHow can this be easily accomplished via the code? I really want to avoid using IB in any of this part of my test app, and I can't find many examples of creating this without IB out there..
Thanks in advance!
- Spam
- Abuse
- Troll
0 • Off Topic Insightful Disagree Dislike Like Awesome- Spam
- Abuse
- Troll
0 • Off Topic Insightful Disagree Dislike Like Awesome