Essentials • 49:51
View controllers support user interface elements that enable users to access the information they want quickly and easily. Find out how you can use view controllers most effectively, not only to support navigation, but also to support device rotation and to reduce memory overhead in your application.
Speakers: Evan Doll, Alex Aybes
Unlisted on Apple Developer site
Transcript
This transcript was generated using Whisper, it has known transcription errors. We are working on an improved version.
Good afternoon, and welcome to Mastering iPhone View Controllers. My name is Evan Doll, and I'm going to be joined shortly on stage by Alex Aybes, and we're both members of the iPhone Software Engineering team. And you've been hearing a lot about view controllers here at WWDC in the iPhone sessions.
And the key point that I'd like to make today is that view controllers aren't just for your first simple application. You can build on view controllers and use them to make a really rich, full-featured, polished app for the iPhone. We use them internally for even our most advanced apps, and we would like you to look at adopting them as well.
So in the first view controller session on Tuesday, we began building a recipes application to show off some ways that you can use view controllers. And that demo has been built upon in the subsequent sessions here at WWDC, and we're going to keep working on it today. And specifically, we're going to learn about being a good memory citizen and how that can have a real positive impact on your iPhone app. And then we're going to customize navigation. This is a very common place to add buttons and other types of controls in your iPhone app.
Next, we're going to learn about presenting content modally, and what that means exactly, and what some of the situations are where you might want to use it. And finally, we're going to put it all together to make version 2.0 of Recipes. Specifically, we're going to combine the navigation and tab bar application flows, which is something that a lot of people want to do in their apps.
As a quick refresher, if you didn't make it to understanding iPhone View Controllers, we like you to think of view controllers as the building blocks for your iPhone application at the controller level. And they make it really easy to adopt the most common application flows and design patterns in your app without needing to roll your own and write a bunch of code.
This allows you to spend time writing the code that you care about because your time and resources are limited. So with that in mind, let's jump into the first advanced topic on view controllers and learn about being a good memory citizen. Some of you may already be familiar with this, but on the iPhone, there's a different set of constraints from on the desktop or maybe some other platforms that you've worked with.
And specifically, there isn't virtual memory. So when we begin to run low on available memory, some tough choices need to be made in terms of deciding who gets to run and who doesn't. Additionally, your application is not a virtual app. It needs to coexist with some system applications which may also be running in the background. For example, Mail and the iPod application.
And if your application begins to consume memory and not release it when it's done with it, eventually, we're going to have to kill or maybe more nicely put, terminate Mail and iPod. And, you know, this isn't going to have an effect on your application, but your user is going to notice it because their music just stopped playing and Mail auto-fetch and push in the background has been halted.
If your application continues to use Mail, it's going to have a lot of problems. So if you're running out of memory, unabated, eventually, your app is going to get terminated as well. And this has a definite noticeable negative impact because to a user, it feels like your application just quit. And obviously, this is a bad thing.
So we allow you to deal with these situations on the iPhone by allowing you to respond to memory warnings. And if you respond to memory warnings effectively, you can avoid these sorts of situations when your app is running. So let's talk about how exactly you respond to memory warnings.
There are a couple of ways in which memory warnings get to your application. There's a notification that you can listen for at the application level. But probably the more useful one is that every view controller which is currently instantiated in your application will get called with a method that's called did receive memory warning.
And the default implementation of this method will release the view that's being managed by your view controller if it's not currently being shown on screen. And this is something that we've heard a lot of people asking about here at WWDC. They wonder about, you know, if their application has a very deep navigation stack, what's going to happen? You know, is their application going to run out of memory? And the nice thing here is that all except for your top view controller in your navigation stack will automatically release their views if they're not being displayed.
And we're able to do this because either A, you're loading your view controller's view from a nib. And the view controller keeps track of the name of the nib that you loaded. So when it's time to redisplay, if the view is purged, it's able to bring it back in from the nib. In the second case where you overrode load view in your application, we're just able to call load view again as needed to lazily regenerate your view when it's time to redisplay on the screen. So this is some automatic behavior in view controller that you get for free.
Additionally, it's your responsibility in your view controller subclass to release any other expensive resources which you may be holding onto. So the way this may look in your view controller subclass is that you'll override the did receive memory warning method. And you'll always call through to super to make sure you get that view releasing functionality. And then you'll release any other expensive resources. Additionally, if you're holding onto references to subviews of your main view, you're going to want to clear those out as well, because they're not going to be valid anymore.
Let's talk a little bit more about what kind of resources you want to release in this method. The big candidates are resources which are expensive and re-creatable. So things like images, sounds, maybe even movies that you've loaded up and queued up to play. If they aren't currently being used on the screen, then it's a great time to purge those resources.
Additionally, any type of cached data which you may have loaded in your application, perhaps to improve performance, this is the time to get rid of it. So if you've loaded data from a plist or from a SQLite database and you're holding a big array of stuff in memory, you're going to want to release it. So yeah, here's our app, our view controller, it's releasing, everybody's happy. Nobody got killed.
So an important step here is once you've implemented, did receive memory warning, you're going to want to verify that your application behaves in the way that you're expecting. So there are a couple of ways to do this. And there's really no substitute. So we're going to take a look at that right now with a demo.
So as you can see here, we've got our recipes application, which we know and love. And I'm just going to run it real quick here so that those of you who haven't seen it can see what's going on. We've got a list of recipes at the top level, then some detail about that recipe, and we can even view a photo for the recipe. There are some other aspects to the application, but that's the main gist of it.
Now, if I go to the Run menu in Xcode, and I go to Start with Performance Tool, and I use the Object Allocations template for instruments, We're going to launch the application and also profile the memory usage in the background. So as you can see here, there's something in our application which is ramping up the memory usage on launch.
And if I go to the hardware menu in the simulator, I can simulate a memory warning to see what's going to happen in the case of a low memory situation. So here I'm going to trigger that, and it doesn't really look like anything happened. So we want to fix that.
Let's go back in here, and just for kicks, we can even drag on the instrument's timeline. And it looks like we started at about 8 megabytes of memory usage. And then due to some resource that we were loading, we actually went up close to 12 megabytes. So if we can release that resource, that'll help our application avoid termination.
Let's go into our recipe list table view controller. And it looks like in here we've got this new thing being created in the init method called expensive resource. Wow, that sure looks suspicious. This is a little bit of a contrived example, but we really want to just show you how to use the tools.
And then the specifics of your application's memory usage are up to you to manage. So you've got this expensive resource. And just like any good Objective-C developer, we're releasing it in the dialyc method. And in your desktop Mac OS X application, this would probably be enough. You might do some more aggressive purging, but really this is the bare minimum.
So what we want to do is release this object in response to a memory warning. So as you can see here, we've already overridden the did receive memory warning method. And what I'm going to do here is add a little bit of code to release our expensive resource-- if only it were this easy, right-- and nil it out.
And an important thing to remember here is that in your application, you're going to need to make sure that you have some lazy loading built in so that you can release this expensive resource and then bring it back as needed if you're going to need it down the road. So I've added these couple lines of code. I'm going to build my application. And then I'm going to go again and run, start with Performance Tool, Object Allocations.
And as you can see here, our memory is ramping up again. And if I go to the hardware menu and simulate memory warning, and even if this view controller, where the expensive resource was being held, isn't currently being displayed-- in fact, especially if it's not the one being displayed-- then we want to make sure that that resource gets released. So let's try it out. Cross your fingers.
And it looks like we dropped off a nice little cliff there in terms of memory utilization. And we can even check here using the timeline. It looks like we dropped down by four megabytes or so. So that was a pretty expensive resource. So the key here is that you're going to want to verify in your application, using the simulator, that your expensive resources get released. Can we go back to the slides? : So yeah, release anything which can be recreated later, and especially if it's expensive.
On top of that, you can use tools like instruments in the simulator, which is a really quick place to do a first pass and see how your application behaves. And there really is no substitute for on-device testing of this sort of thing. So you'll want to make sure you test your application in a wide variety of situations to make sure that it has a great user experience. Next, I'm going to ask Alex to come on stage, and we're going to talk about customizing the navigation in your UI Navigation Controller-based app. Alex? Alex Aybes : Thank you, Evan. Thank you.
All right, so now we're going to talk about customizing the navigation. Before we get into this, let's go back to what we talked about earlier. Let's go back to the basics of navigation controllers. This is stuff we've covered in the understanding view controllers, but I'm just going to review a little bit.
So again, the navigation controller manages a stack of view controllers. Make sure that the view controls animate properly when you're pushing or popping view controllers. It also manages the navigation bar and always guarantees that the navigation bar will reflect the view controller that is displayed at the top of the stack. It will also, as you can see here, display a little back button with the title of the previous view controller.
All right. Now that we're clear on the basics, customizing the navigation. Why would you want to do this? Well, the navigation bar is actually a great place to put buttons. This is at the very top of the screen. This is the first thing your user is going to see when they're actually opening your application.
As they scan down, scan your application, oh, buttons at the top. So this is a really good place to put your controls and provide user with functionality. So here we have a couple of examples of this. As you can see, the clock application and the phone, the recents, and the phone application.
In those two applications, we have a number of buttons. You see in the clock, we have an edit button at the top left and an add button. And in the phone application, the recents, we have a toggle item, a toggle button in the middle, as well as a clear button.
One thing to note about those buttons is that every single one of them actually acts on the entire screen full of content. It is very common in the navigation bar to put buttons that actually modify the whole screen full. In the case of clock, the edit button will actually change the appearance of every single cell in that screen full. In the case of phone, the toggle switch will actually change the contents of the view.
Switching from displaying all the calls to just the missed calls. This is an important thing to keep in mind. It's usually affecting the entire screenful. So how do we go about customizing? What is the first thing we need to know about? Navigation items. It's an important bit. Each view controller has a navigation item. The navigation item is a special object that describes the appearance of the navigation bar when a view controller is actually displayed.
The navigation item has three important properties: the left bar button item, the title view, and the right bar button item. Those are displayed in the navigation bar. Left bar button items, right bar button items. Bar button items. All right, let's take a look at those. A bar button item is pretty much like a button that can be placed in the navigation bar. It can have a title or an image. We also provide convenient methods to create system items. We'll take a look at that in a second.
Since it's like a button, it needs a target and an action. The target is the object that's going to receive the message when the button is actually pressed. And the action is a selector, a method that's going to be called when the button is pressed. In most cases, the target is actually going to be your view controller. Again, we're customizing the appearance and navigation bar for a particular view controller.
And since the view controller is where you put your application logic, it makes sense to have the target be that view controller. So how do we actually create a button to put in the navigation bar? This is what the code looks like. You have a bar button item, allocate, and with a title, in this case, we want to put a foo button in the navigation bar. So we initialize it with a title.
We also set its side to be bordered so we actually display borders around the button. And then, importantly, here, we set the target. This is code that will live in the view controller, so the target itself, the view controller. And when that button is pressed, we want the foo method to be called. So we pass in the selector foo.
Another common thing to see, that you see in the navigation bar are, for example, an Add button. We provide a very convenient way of creating those. Those we call system items. So, to create one of those, you're going to call UI BarButtonItem, Alec, in it with BarButtonSystemItem, and you pass the system item add to it.
This will create a button that already has a little graphic for adding a whatever you're actually adding. In this case, a recipe later. Again, the target itself, the view controller, and the method that's going to be called in this particular case, the add method. All right, simple enough. Another very common button you might have seen in different applications, the Edit Done button. So let's take a look at this one.
Again, this is a very common pattern. A lot of applications actually edit the contents of the screen with an edit button. As you can see in the movie here, the edit button is special. It changes color when it's switched, changes title when it's toggled. And in this case, in the recipes application, we're also going to change the appearance of the table view.
This is actually really simple to do. Each view controller can actually create an edit button item. That button item has all the right characteristics. It has the title, it changes color, there's all those things. In addition to that, it is already wired to the view controller that created it.
and to a special method we're going to see in a second. So how do we actually create that EditButtonItem? It's very simple. You're going to ask yourself, in this case, the RecipeListViewController, which is the view controller we are customizing the navigation bar for, and you're going to set the leftbar button item of the navigation item of that view controller to be the EditButtonItem. To get the EditButtonItem, self.EditButtonItem. That creates this EditButtonItem. Again, the button is actually already wired up to the setEditingAnimated method. This is a special method that gets called whenever that button is pressed. So the view control actually keeps track of the current editing state and such.
If you want to have custom animation in there, if you want to actually change the contents of your view to reflect the fact that it's now in edit mode, you can put your code right there. One nice little thing here, one advantage of using the UI Table View Controller is that it already does that for you. It implements this method and actually switches the state of the table view accordingly. So you'll actually get the same UI as we just saw in the recipes application in the little movie at the top.
All right. Add button, edit button. Next one we're going to look at is the title view. The title view we've seen in the phone application, a little example. You can actually put any arbitrary view you want into this title view. It doesn't have to just be the title.
In this case, in the recipes application, we're going to add a little toggle button, very much like the phone application has, the recents in the phone application. In this case, it's going to toggle the sort ordering for the list of recipes. How does this work? A couple lines of code.
You create a segmented control, and once you have that segmented control, you set it as the title view for the navigation item. Again, self navigation item. This is code that lives in the view controller. Self navigation item, title view equals segmented control. And that's all you really need to do. We'll take care of putting it in the navigation bar for you. So I've covered the three different properties we had, the left bar-bar 9M, the right bar-bar 9M, the title view. There's one more that I haven't talked about yet. It's the back button.
Wouldn't it be nice, if you look at this example, we have a very long back button. The go for the is actually quite long. And it's even forcing the category, the title of the current view controller, which is really the important view controller because it's the front most. It's forcing the title to be slightly offset, off-center, not looking so great.
Evan Doll, Alex Aybes Wouldn't it be nice if we could actually have a shorter title for the back button? Well, you can. So how does this work? Very simple. We have a property on the navigation item that I haven't talked about yet. It's the back bar button item.
This is actually a property that lives in the view controller, not in the-- in this case, not in the category view controller, but the previous view controller, the detailed view controller, the one that had the recipe, the actual recipe. That view controller can say, when I'm the item just below the top, I want my back button to look a little differently. My title is too long, so don't display that in the back button. Actually customize it.
And for this, we're going to create just a UI bar button item using a title that's actually shorter than the regular title. And there we go. We set that at the back bar button item of our navigation item. Again, this is the view controller that's before this one.
All right, well, with this, I'm going to ask Evan to come back on stage to do a little demo. Evan? So let's do that last thing first, because it confuses a lot of people where to do the back button customization. So what we're going to do-- actually, let's look at this in the application first. I'm going to build and run.
And as you can see here, when I pick the-- I'm not even going to try to pronounce it-- the back button kind of has an unwieldy size to it. We'd really like to show a shorter title here. So I'm not going to customize the category view controller. I'm going to customize the recipe detail view controller, which is being represented by the back button. So here in the recipe detail view controller code, it looks like we're setting our title in the viewWillAppear method.
So to go with that, I'm going to create a UI bar button item, which will be represented as a back button. And I'm going to set the title to be something shorter. And actually, the style and the target and the action here don't really matter. We're going to override those automatically in the navigation controller, because we want all back buttons to behave in the same way. Next, I'm going to set our navigation item's back bar button item to be this object which we just created. And then I'm going to release it, because now our navigation item is the owner. With this code written, let's try running one more time.
And you'll see here that when I navigate in, we've got a much shorter back button title. This might seem like a kind of minor cosmetic thing, but it's actually a nice way to add some polish to your application. Now, let's jump in and add an Edit Done button here on the left-hand side of the screen. This is such a common thing. So many applications toggle between an edit mode and a non-editing mode that you can do this with a single line of code.
So here in my recipe list table view controller, which is this guy right here, it looks like we're setting up the title and then we're setting the image. Let's set our navigation item's left bar button item to our own lazily created edit button item. Once I've written this line of code, let's build and run.
And you'll see that we get an edit done button here in the top of the navigation bar. And it automatically gets transitioned out when we navigate away. It does the right fade or movement, whatever. I don't even remember what it's supposed to do as it disappears. But that gets managed for you automatically.
And if I toggle it, it's going to toggle the state of the table view. And this is because we're using UI Table View Controller as our base class here for this screen full of content. So we get that little bit of functionality pretty much for free right there. The button updates its appearance. And if you actually want to implement the deletion here, there are a couple more methods which you need to write. And that's actually going to be covered in the advanced or mastering iPhone Table View session.
So let's add an Add button on the right side of the navigation bar. So we're going to do that with a system item, like Alex mentioned before. So we're going to create a bar button item using the system add item. And we're going to set up the target action. So the target will be self, and the action will be the add method, which we're going to define in a second.
We're going to set it as our right bar button item, and we're going to release it. And if you look below here, we've actually got a stubbed out add method. We're not going to fill this in just yet, because that's going to be part of the next segment. So let's build and run.
And here you can see that we now have the standard Add button in our navigation bar. And we wanted all iPhone applications to have the opportunity to present this type of a standard Add button. So you can do it like this. Lastly, let's add that toggle button in the middle here so you can switch between ascending and descending sort order with your recipes.
You can really add any sort of custom view, but in this case, we're going to use a segmented control. So first, I'm going to create the segment control, just like I would any other UI kit view class. And I'm going to give it an array of two items, A to Z and Z to A.
And then I'm going to set up a couple of initial properties for it. The style is going to match the navigation bar. And the initially selected segment is going to be the first one. Next, I set the target in action. And this is a standard UI control way of doing things. The selector is going to be toggle sorting on our view controller.
Then I'm going to set it as our navigation item's title view. Again, the navigation item is the way you get at all of the sort of view attributes that show up in the navigation bar. And finally, I'm going to release it. And you can see below, we've actually implemented the toggle sorting method already. It's going to send a message over to another class, which manages the underlying data. And it's going to tell our table view to reload. So with this little bit of code written here, I'm going to build and run.
And you can see we get this segmented control up here. We can toggle the sort order of our recipes, or in your application, you could add any sort of control to do whatever you like. And again, all of these buttons here at the top, we manage the positioning and the appearance and the transitions so that you don't have to. And this is a great way to have a consistent look and feel in your iPhone application. That wraps up the demo. Alex, back to you. Thank you, Evan.
What did we just see? Again, the navigation bar is a really good place to put your custom buttons and allow the user to have access to functionality. It's the first thing they're going to see when they launch your application. It's at the very top of the screen. So, add navigation button. If you have a use for it, customize the title of your. It's very simple. Again, the back button title. It seems like a minor thing. It's actually a really nice polish item. It really makes your navigation bar look cleaner and less cluttered.
You've noticed in the demo we didn't actually implement the add button. And there's a reason for that, because as you might have noticed in a number of the app, whenever you have an add button, we actually present a new view controller that comes on top and covers the entire screen.
So how does this work? And how do we-- how does this work? This is actually what we call presenting content modally. It's good whenever you want to pick from a set of data or create new items. It's a big context switch for the user. So how do we actually do this? Where do we do this? Here, let's take a look at a couple of examples.
Here in the Clock application again, we have a plus button at the top right. When you press that plus button, we're actually going to show a new alarm.
[Transcript missing]
Another example of this is the SMS application. When the user is going to compose a new SMS, we actually, when the user presses the new SMS button, we're going to present a composed view on top of everything else, covering everything else.
In addition to that, in SMS, we're also going to let the user pick people from the address book by clicking this blue button. And then the user can cancel out of both view controllers one at a time. So again, we can actually present multiple view controllers on top of one another.
So how does that work? In order to present a mobile view controller, we have a simple method. Here in the recipe list view controller, again, this is the list of recipe, We're going to create an add view controller. It's a special type of view controller we've implemented that lets you edit the initial things we want to edit in a new recipe.
So we create that view controller, and then call presentModelViewController, passing in the add controller, this view controller that's used for adding. And we can also pass in an animated flag, depending whether we want to animate this or not. One thing to note here, we're in the recipe list view controller. So this is the one that's actually going to present the new view controller. This is what it's going to look like. Press the button. The view controller comes up and covers the screen.
Once we've done that, let's say the user wants to cancel, the user is done entering data, we're actually going to need to dismiss it. How do we dismiss? It's important to note here, we have a simple method, actually dismiss model view controller, that will dismiss the view controller. But it's important to note here that this is actually done in the recipe list view controller. This is the view controller that's underneath the add recipe.
We have our recipe list, then we bring up the add controller on top of it, and it's actually the recipe list view controller that's going to call dismiss. Or rather, we're going to call dismiss on the recipe list view controller that's down at the bottom. That will dismiss. the model view controller.
So again, whichever view controller you present the model view controller on should be the same one you dismiss the model view controller from. All right. One thing you might have noticed in this example is that we're covering the screen with the add view controller that also has a navigation bar at the top. This is actually a separate navigation bar, and therefore, a separate navigation stack.
You can have two full navigation stacks on top of one another that are independent from one another. So here we have the Recipe List View Controller. Again, we present the Add Recipe View Controller. It has its own navigation bar at the top, and therefore its own navigation stack, because it's a navigation controller.
What this means is that you can actually change the navigation stack underneath your model view controller. You can push and pop view controllers underneath the model view controller that's currently being displayed. This might sound a little odd, but this is actually very useful when you're creating new items. You might have noticed that in Address Book, for example, in the Contacts application. When you create a new item, we actually bring you to the new contact when you dismiss.
So this will look like this. Again, we start the recipe list, we create a new recipe, we save it, and we actually get to view that full recipe. How do we do this in code? Well, it's pretty simple. This is the same method in the recipe list view controller that's going to dismiss the model view controller.
In this one, we're going to create Sorry, yeah. In this one, we're going to create the next view controller we want to see underneath. So the actual recipe detail controller. And that's where we're going to show the new recipe. Then, again, this is the recipe list view controller. Remember, this is the one that's at the bottom of the stack.
That's underneath the model view controller, rather. We're going to get its navigation controller and push a new view controller on top of it. We don't want to animate this because this is actually covered by the model view controller, by the add recipe. Once it's done, we're going to animate out the model view controller, the add recipe. All right, this is a lot of hand waving and gesturing, lots of view controllers. Let's actually see that. We're going to write some code.
So here, we're back in our recipes application. If I run this, we have an Add button. Again, we haven't implemented it yet, so it doesn't do anything. Let's go back to the code. We're going to do this in the add method we've defined earlier. Here's the add method.
The first thing we're going to do is actually create that view controller that we're going to display on top of the list. So we create a recipe add view controller. This is the type of view controller we've defined. I'm going to show you briefly. The recipe add view controller, again, it's a very simple subclass, the UI view controller. One interesting thing, it has a delegate, and it defines delegate protocol that has a single method. The recipe add view controller did add recipe.
One interesting thing to note here, it can actually pass nil for the recipe when the user has canceled. All right. We'll talk about that a little bit more, so don't worry about it. All right. Back in the recipe list table view controller, in the add method, we've created the recipe add view controller. We're setting ourselves as the delegate.
Next thing we need to do is actually put that view controller in a navigation controller. That particular view controller is not a navigation controller, but it prefers to live inside a navigation controller. So we're going to put it as the root view controller of a new navigation controller.
Next, we're actually going to present that new view controller. In this case, we're presenting the navigation controller. Remember, the add view controller is actually inside of that one. And we do want to animate, show the user what's going on. All right, once we've done this, we can actually release the navigation controller and the add controller, because the add controller is part of the navigation controller. And the navigation controller has now been presented as a modal view controller, and it's being tracked. All right, when we run this.
Actually, I forgot something. Let's go back to Xcode. I should listen to the warnings. All right. I said we implemented this delegate. We actually set ourselves a delegate. Xcode is not happy because we didn't actually implement the delegate protocol. So let's go back to our header, implement that protocol.
and implement that one method I showed you a little earlier. So the recipe add view controller did add recipe. This is where we're actually going to add this recipe to our model. So that's the first thing we're going to do. The recipes controller again is our model object. So we're going to add the recipe to it. Next, we're actually going to tell our table view to reload its data.
This is, again, the list of recipes. So it needs to reload because there is a new recipe in there. The next step is to actually show-- this is where I mentioned to you earlier-- we can change the stack underneath. So we're going to show the recipe. And this method is just a simple method I'm going to show you. It just pushes a recipe detail view controller onto the navigation controller. So actually go back. Here we show the recipe. Great.
Next thing we need to do is actually dismiss the model view controller. And this one we're going to animate, because this is direct user action. All right, with this, we're going to run. No more warnings. Excellent. All right, so when we add the new recipe, There we go. We have a navigation controller that comes on top of the current stat. I can cancel. It dismisses it.
If I add a new recipe, chocolate number five, And save, I'm actually brought directly to this new recipe that I just added. So I can go directly and edit the category, for example. So this is a very nice way to let the user know what just happened. All right. With that, back to the slides.
So what did we just see? Again, whenever you need to present content, whenever you need to add or pick from an existing set of data, present your view controllers modally. We actually provide a number of pickers for images or people that you can present modally and you should present modally. In addition to that, you can push or pop view controllers underneath the modal view controllers.
This is very helpful for the user. It really lets the user know what just happened and everything. But you shouldn't abuse it. Don't just switch the entire stack underneath the MoMA view controller and users are going to be all lost. Just do simple things like presenting what you just added. All those things being done, the navigation bar customized and everything, we're actually going to let Evan back on stage, and he's going to put all those things back together.
[Transcript missing]
Let's take a look at it, just for the fun of it. All right, we have a great chocolate cake, et cetera, et cetera. Great. All right, let's actually merge those new view controls into it. We actually have written those different view controllers. Here we have the timer, very simple subclass of UI View Controller. We also have the converter.
The converter is actually a hierarchy of different view controllers. So we have a unit converter table view controller. That's the base, and that will let you drill down into different unit conversions. All right, to convert our app from being just a simple, single navigation controller into this arrangement and combination of tab bar and navigation flow, we're going to go to the application delegate.
Here we have the existing Net Application Delegate. And we're going to just delete all of it. All right, this is just eight lines of code that we deleted. No need to worry. We're going to recreate this entire flow in there, step by step. The first thing we're going to do is actually create all the different view controllers we need to add to the tab bar. So let's start with our recipe list table view controller. This is the one we were just looking at earlier.
It's a subclass of UI Table View Controller, so we initialize it with the right parameters. Next thing, this needs to live in a navigation controller, so we're going to create a navigation controller for it. So UI Navigation Controller, in it with View Controller, Recipes View Controller. Once we've done that, we don't need to hold on to the Recipe's View Controller because the one we really want is the Recipe's Navigation Controller.
That's our first item. The next one is the unit converter. So let's create our unit converter. This one, just call AlecInit to create it. That's how it likes to be instantiated. And then again, we're going to put that in a navigation controller. Same thing as before, Init or a navigation controller with a root view controller, which is the converter.
Great. The third item we want to put in there is the egg timer. For this, we're going to create a UI View Controller using the timer view controller class. This one is instantiated from a nib. We've got one of each in here. So again, very simple. This one does not need to live in a navigation controller. So we're done for the timer. Excellent. Next step is to create the TabBarController. So for that, UI TabBarController, Alec in it.
Now we need to actually set the view controllers that are going to be living in the tab bar. Those are the three that we just created. All right, the way we do this-- TabBarController.ViewControllers equals an array of the three view controllers we created. Again, the Recipe's Navigation Controller, the Converter Navigation Controller, and the Timer View Controller.
Once we have this, We just set the tab bar controller's view to be the subview of the window. This is essentially the same code that was there before, except it was setting the navigation controller's view to be the subview of the window. But now, a tab bar controller is the top one. And then we make the window key invisible. Great. So now let's run this.
Actually, before we run this, let's actually manage our memory properly and release all those view controllers we just put into the tab bar controller. Okay, so now we can run. And there we go. Not so much code, and we have a recipe list here, and our first item. You can actually drill down in there. And then we have a unit converter. Beautiful unit converter to convert weight, imperial metric.
And then we have an egg timer. Excellent. And I can go back to the recipes, and you see I'm still in the same item. I can click again, goes back to the top level, et cetera, et cetera. So very simple to combine those two different flows. All right. That's it for the demo.
Evan? Thanks, Alex. So as we saw right there, we were able to assemble a complex application from simple parts that we were able to develop individually without a whole lot of dependencies on one another. And to do this, we nested navigation controllers inside our TabR controller. That just about wraps up the main points that we wanted to cover today.
So to make a great iPhone application, it's essential to respond to memory warnings. This really helps you to have a smooth user experience that doesn't unexpectedly quit on your user. Also, the navigation bar is a great place to put buttons and other types of controls. It's one of the first places your users will look for these types of things when they navigate to your view controller.
One of the things you may commonly do here is add new data and pick from existing data by presenting content modally. Whenever you present content modally, you want to give your user a way to back out. So a cancel button to go with your save button is very common.
[Transcript missing]
If you have questions about view controllers after WWDC, I'd encourage you to get in touch with Derek Horn. He's our application technologies evangelist, and he can help you out with questions, or he's a great person to submit feedback to if you have requests for the view controller classes. And the view controller docs are really great. They're very thorough, and they cover a lot of the same ground that we've been going over in these sessions here.