iPhone Tutorial Two — Combining UITabBarControllers, UITableViews and UINavigationControllers using Storyboard
Hey guys, so after the last tutorial I figured I would try and help some people with something that has been troublesome to developers in the past — combining tab bars and table views. Again, I am assuming you know the basics of iPhone development and are trying to use Xcode 4.2 to get a jump on the future of iOS development. If people ask for tutorials, I will create some explaining some things here I graze over. Okay so let’s get started.
First and foremost, I can be a lazy developer at times (i.e. I’d rather use some templates provided by Xcode, just to save 20 minutes). So to start off, let’s create a new project using the Tabbed Application Template.
You will see the App Delegate, Storyboard, and View Controllers for both tabs. The template also include icons for us (both for lower resolution iPhones, and the higher iPad, iPad 2 and iPhone 4). Delete the icons here, as some will be added later on, or keep them (If you want to follow this tutorial to the T, we will be adding some I created). I really prefer the layout of this compared to the older Xcodes and their Tab Bar templates. It helps split everything up for you, and I feel it is less crazy when they are spaced out, since it helps you concentrate on one tab’s view at a time. If you wish to follow along, created a new group labeled “Images” and place images uploaded below inside.
Lets focus on the First View first.
Select the bottom part of the Tab Bar, navigate to the Attributes inspector, and change the title to “UIViewController” and the image to “1.png”.
We are done with the first view. Since this tutorial does not really have much to do with UIViewControllers, we can just leave this how it is. Now we are going to get our hands a little dirty. First, scroll down to the Second View Controller and delete it. Don’t be worried, adding items to the Tab bar is painless. Now, go into your Objects on the bottom right, and drag out a Navigation Controller (the gold spherical one).
You will notice that two windows will appear on the screen. The left one is the screen that actually contains the Navigation Controller, and the right is the Root Controller. The root controller is what you wish to display on the screen alongside the navigation controller. To do some minor tidying up, and to keep my OCDness at bay, I am going to change “Root View Controller” to “Table View”. Now, just because we have the Navigation Controller in the storyboard, does not mean it is connected to any implementation/header files whatsoever. So, let’s get the Navigation Controller all hooked up. First, Ctrl + Drag from the Tab Bar Controller straight down onto the Navigation Controller. You will notice that two options come up, viewControllers and performSegueWithIdentifier. Select viewControllers, and you will notice that you now have another tab added, and and arrow leading from your Tab Bar Controller to your new Navigation Controller. Be sure to also change the text to “UITableView” and the image to “2.png”.
Now we need to have this tab actually display something when this tab is selected. To do this, click on the bottom-rightmost scene, titled “View Controller – Root View” and make sure that the View is selected on the left Scene Panel (You can also do this by just double clicking on the view). Go to your objects and grab a Table View (NOT the controller) and drag it within your selected view. Now, with the View Controller – Table View selected, go to the Identity inspector and change the class to “SecondViewController”, as shown below:
This now means that the table view will be getting it’s data from the SecondViewController.m/.h files. Before we get to programming, make sure you Ctrl + Drag from the Table View to Second View Controller – Table View and select both Delegate and Data Source. Without this, the data we create will not get loaded into the table view. Now, let’s actually start doing some programming! Since the Table View is getting its data from the SecondViewController files, we need to also write the delegate functions. Lets start with the SecondViewController.h file. We will be creating an NSMutableArray of dummy objects, along with using a setupArray function to create the array. I have learned that not much code should be done in ViewDidLoad, and that if you just have function calls it sometimes helps solve some problems later on.
To anyone that has done programming with table views, this should all look familiar so I will not be going into it. If you need assistance, I can write a tutorial about it (I probably will anyways). If you run the application in the simulator, you will see something similar to what is shown below:
However, you’ll also notice that if you select a cell, nothing gets pushed onto the screen. This is because the didSelectRowAtIndexPath is empty, and I left it like that for a reason. The Apple developers in Cupertino changed the way the delegate function deals with views, since normally you would just pop a view onto the screen using a modal view controller or navigation controllers, there is a slight difference now. So lets go back to the storyboard file. So we will be using a View Controller as our detail view, so grab one out of our objects and place it next to the Table View Controller. Now if you click on the actual View Controller and go to the Attributes Inspector you will see something new: “Identifier”. This is basically a way to init certain views with certain scenes from the storyboard. Let’s just call this “Detail”.
Now lets create some .h/.m files for this new view controller. Go to File > New > New File and select UIViewController subclass. Make sure the “With XIB for user interface” is not checked, and call it “DetailViewController”. Now, go back to the View Controller we added in the storyboard, and change the class to “DetailViewController”. Lets go to the DetailViewController.h file, and add a IBOutlet UILabel.
Also, do not forget to @synthesize the rowNum in the DetailViewController.m, as well as connecting the IBOutlet in the storyboard from Detail View Controller to UILabel. Alright, now to look at some new Xcode 4.2 functions. First, #include “DetailViewController” at the beginning of your SecondViewController.m file, after your initial #include. Lets look at the code I entered below, and I will try to explain it as best as I can.
So if you begin to look at it, it looks pretty normal until you see the [self.storyboard instantiateViewControllerWithIdentifier:@"Detail"]; Well, I think the self.storyboard is obvious, you are calling this because this is the container for all of your Scenes (or nibs). Now remember when we set the Identifier for our DetailViewController Scene? That was for this. I like to think of it as using an initWithNibName:, in that the Identifier is sort of like the scene’s name, and that is how they are associated within Xcode. Next, we just push the view with the navigation controller, followed by changing the text in each of the detail views to correspond with the row that was selected. And that should be it! I hope this was informative, and I hope you can use this knowledge again in the future. If you have any questions, please feel free to post a comment, and if you want to see the source code for reference, it is below.
Also: I appreciate the amount of views I have been getting lately and it is making me overjoyed. Since I am in college, buying new gadgets to test on is nearly impossible. If you feel like I helped you, please spread the word and if you can, hit the “DONATE” button on the right hand side and donate a few dollars my way. Anything is greatly appreciated.