Configure player

Close

WWDC Index does not host video files

If you have access to video files, you can configure a URL pattern to be used in a video player.

URL pattern

preview

Use any of these variables in your URL pattern, the pattern is stored in your browsers' local storage.

$id
ID of session: wwdc2008-324
$eventId
ID of event: wwdc2008
$eventContentId
ID of session without event part: 324
$eventShortId
Shortened ID of event: wwdc08
$year
Year of session: 2008
$extension
Extension of original filename: m4v
$filenameAlmostEvery
Filename from "(Almost) Every..." gist: ...

WWDC08 • Session 324

iPhone for Mac Developers

Essentials • 58:34

Cocoa Touch uses many of the same fundamental technologies and design patterns as Cocoa for Mac OS X. Discover how you can make the most of your experience with Cocoa for Mac OS X when you start developing for iPhone.

Speaker: Corbin Dunn

Unlisted on Apple Developer site

Transcript

This transcript was generated using Whisper, it has known transcription errors. We are working on an improved version.

Welcome to iPhone for Mac Developers. My name's Corbin Dunn. I'm a Cocoa software engineer, and I work on the Cocoa team. Specifically, I work on the Cocoa user interface framework, some of the UI elements, and I've also had the opportunity to work on the iPhone, work on UIKit.

So iPhone for Mac developers, this talk is geared towards the Cocoa AppKit Mac developers. And we expect you to have a basic understanding of Cocoa. And what that means is we hope you're familiar with the basics like Innes arrays, CFArrays, Innes dictionary, Innes string, et cetera. You understand our AppKit design paradigms so you know what Model View Controller is.

You know how to work with the responder chain. You understand our common AppKit names, behaviors, and the way we do things. You're also familiar with Innes views and how to do drawing. And you probably are familiar with hooking up target actions of controls. In addition, you probably have some experience with tables and working with cells.

So what are we going to do in this talk? What are our goals and expectations? Well, if you don't know by now, the iPhone counterpart to AppKit is UIKit. And we're hoping that you can take your existing AppKit and Cocoa skills and migrate them over to the iPhone.

What we're going to do is we're going to cover a lot of classes that are very similar to what's in AppKit. We're going to compare and contrast them and in particular highlight differences so you know what to do and what not to do. Things that we aren't going to do, we aren't going to cover any new classes that are very specific to the iPhone.

Overall, what we're going to cover, well, first, we're going to talk a little bit about application architecture. Second, we're going to talk about drawing. Third, we're going to cover views and controls. And fourth, we're going to cover events. So let's get right into it and talk about application architecture.

Inside here, we'll cover application design and see how to actually develop your applications and lay them out. We'll talk a little about controllers and the class hierarchy. And then we'll move on and do a quick demo inside of Xcode and Airface Builder to see how it all works together. Let's jump right in with application design.

Let's take a look at the architecture of the Mac and the iPhone. You should already hopefully be familiar with this. So at the bottom level there, you have the core operating system. On top of that, the core services like core foundation, CF network, address book, and other core frameworks.

On top of that, we have our media frameworks. Things like OpenGL, Core Animation, Quartz Core, and all the core graphics stuff. If you're building your Mac applications, you'll be using Cocoa. And that consists of AppKit and Foundation. And the iPhone counterpart is Cocoa Touch, which is UIKit and Foundation.

So the iPhone operating system is very similar to the Mac operating system. And what we did is we took all the modern parts of the Leopard 64-bit operating system and just brought them over to the iPhone. So we have things like exceptions. They're fully C++ compatible, just like they are on 64-bit on the Mac. But you need to keep in mind that throwing exceptions still has a cost, and you should be aware of that.

Of course, the iPhone doesn't actually have a 64-bit processor. We have full Objective-C 2.0 support, so the iPhone takes advantage of the app property syntax. And if you look at the UI kit headers, you'll see app property used throughout. takes advantage of 4N and fast enumeration. We also use optional for formal protocols. So you see all our delegate and data source methods using formal protocols with add optional or at required methods. One other note, garbage collection is not available on the iPhone.

So let's talk a little bit about application design. You're going to design your iPhone applications in ways that are also very similar to what you're doing on the Mac operating system. You're gonna basically use nibs, layout your application, gonna hook up your target actions inside of it. You're gonna add controllers in the nib, and you're gonna design it that way.

Let's look at an example of how you would be doing it on the Mac. So you have something like your main nib.

[Transcript missing]

Now, you're probably using NS document-based applications and have a document for each window. You could have one document, you could have two documents, you could have a multiple layer of documents. Let's take a quick look at one of them.

Your document may or may not be using an NSWindowController. Behind the scenes, it really is using it. And the WindowController is the thing that references the window nib, which in turn contains the window itself. Inside of Leopard we introduced NSViewController which allows you to easily manage a view nib of loading it and whatnot. And that references the view. It's optional to use a view controller. You may have other ways of loading your views. Inside of the view itself, you'll probably hook up things using target action and you'll probably have bindings that actually does a lot of your UI work.

: The iPhone application architecture. So what does that look like? You have a main nib, just like you're used to. Do you have a main menu? Well, the answer is no, because there aren't menus on the iPhone. Do you have an NS application? Well, yes, but it's a UI application, because the UI kit framework uses the UI prefix.

You also will have an application controller just like you normally would, and it will probably also be the delegate to the application. But a key difference, you probably will have a single window referenced in the main nib. This is the main window for your application. Unlike the desktop where you would have multiple windows, your iPhone application will probably have one window, and you will place the screenfuls of content using different views. In addition, the application controller will probably reference that window itself.

Do you have an NS document inside the iPhone? Well, the answer is no. You really don't have document-based applications on the iPhone. You're working with smaller subsets of data. Do you have an NS window controller? Well, again, the answer is no, because you generally only have one window, so it's not really needed.

Do you have an NS view controller? The answer is yes, and it plays an important role on the iPhone. And, of course, it's a UI view controller. So the view controller will be hooked up to a view nib, which will then contain your view. Your view will have typical target action, just like you're familiar with, but you actually don't have bindings.

And even though we don't have bindings, we found that we haven't really missed them, because you're working with a smaller screen of data. Even though it's not there, you do have KVO, key value observing, and KVC, key value coding, available for you. So you may have one view controller controlling a view, and you may have another one and another one to replace that screen of content that you're seeing.

Let's dive into it a little bit more to really understand how it works. So here's a sample application screenshot. Your application controller will probably reference the window itself. You'll probably have a main view controller that controls the main view that you're seeing. So that view controller will control that main view. The main view itself will have other sub views.

So we just covered a little bit about application design and briefly touched on controllers. Let's talk a little bit more about controllers, view controllers, and a little bit about the class hierarchy. So view controllers inside of UIKit. Another difference inside of UIKit is that we have lots of subclasses of UIViewController that provides a lot of canned code for you to instantly and quickly use. There's things like a UINavigationController, which we'll quickly show in a moment, a TableViewController, PickerViewController, TabBar, et cetera. There's more of these, and we highly recommend you check into them. Some special UIKit differences from AppKit.

Well, UIViewController does not manage the top level objects. So what does this mean? If you have top level objects in your nib, you are required to release them. This is an important difference from the desktop. For more information on view controllers, I recommend going on and seeing Understanding iPhone View Controllers later today at 2 p.m.

Let's take a quick look at one commonly used view controller, the UI navigation controller. So the navigation controller would be hooked up where, again, you have your main application controller. It's going to reference your main view controller. In this case, it's the UI navigation controller. And that's going to manage that main view here.

In addition, it's going to manage that UI navigation bar you see at the top. And that adds things like the forward and back buttons. And the way it does it is you have your sub view controller inside of it. In this case, it's using a table view controller to manage that table you see there.

And what you can do with the navigation controller is it works like a stack. You can stack other view controllers and other views onto it. So you can push another table view controller onto the stack and have it show and replace it with another table view controller. that content easily.

Let's talk a little bit about AppKit and how you work with modal windows. So AppKit has modal run loops, which you're probably familiar with. You can easily do them by doing NS application run modal for window, and you'd have your base window relative to it, and you'd show another one modally.

So how do you do this in UIKit? Because you don't have multiple windows. You really only have one main window. Well, the UI view controller is there to allow you to do modal views. So take a look at this screenshot. Let's say you want to hit one of those buttons and have an image picker come up over it modally so the user can't interact with anything else.

And what you would do to have that other one slide up above it You create your new controller you want to show. In this case, it's another example of a pre-canned one that we provide, the UI image picker controller. So we allocate it. The main controller, which was the first one you saw, calls present modal view controller animated. And that will actually slide up the other one with the view in relation to it modally. Very easy to do.

General application design tips. Awake from Nib. Well, since you're using view controllers, you probably want to use view to load over awake from Nib. And the reason for that is that UI view controller does more things for you than you would expect. For example, you might have other views that you aren't seeing on screen anymore and the view controller may release the views for memory reasons. So it may reload them at a later time. Subsequently, you might get awake from Nib more than once. To deal with that problem, we recommend using view to load to set up the view each time the view is actually loaded instead of using awake from Nib.

In addition, if you have one-time setup for your application, you probably want to use application did finish launching instead of awake from nib. This is similar in AppKit where it's preferred to use that. It's good for performance reasons. One other important difference, the file's owner will not get a wake from nib. It's a huge difference from inside of AppKit and something to be aware of.

Auto release, we recommend following the best practices for AppKit and not really overusing auto release to fill up the auto release pools too much. The C++ conceptions, as we briefly touched on them before, although they are C++ compatible, they really only should be used to indicate any programming errors that you have in your code and they not should be used for any flow control or anything else.

Let's take a quick look at the AppKit class hierarchy. This is a small subset of it. You're probably familiar with you have NSObject up at the top. You have a responder beneath it. You have your views, your windows, and your view controllers. You have controls, tables, buttons, scroll views.

comparing it to a subset of the UI kit class hierarchy. Well, NSObject is still the parent for everything. You do have a UI responder, just like you have an app kit, and you do have the UI view. You have a UI view controller. Some important differences, the window actually descends from the view. So the window's a full-fledged view and not just a responder.

We'll discuss this a little bit more later. Another subtle difference, the table view descends directly from the scroll view. So the table view is no longer a subset or a subclass of UI control. Instead, it subclasses the scroll view itself. We'll talk about that a little bit more later too. So we just covered some view controllers and some class hierarchy. Let's take a quick demo and see how this all fits together inside of Xcode.

Inside of Xcode here, I'm going to go ahead and create a new project, just a regular view-based application. And we're going to call it My App. So some things that are done by default for you is you'll see there's an application delegate automatically created for you. There is a UI view controller subclass that is automatically created for you.

And then there's two nibs, or actually zibs, which will get compiled to nibs. First of all, you have your main window one, which you're familiar with. And then you have one for your view controller. If we take a look at the main window nib, we can see inside of it that we have-- Our app view controller is one instance in here. And we also have the main window that we're referencing.

If we go back to Xcode and open up the View Controller nib, We can see we have our single view where we can actually start adding content. So let's go ahead and just add a button down here. And just quickly show how easy it is to hook things up. We can go back inside of Xcode and add some code to the view controller.

So if we want to hook up a typical target action, it's very easy to do. You're familiar with your IB action signature where it's the method name and then the first parameter is the sender. But inside of UIKit, we went a little further than what AppKit did, and we allow you to optionally have the sender parameter. So you could have button touch up inside without the sender.

And we took it another step further, and we also allow you to have the event to be passed along with it. So I'm going to go ahead and quickly : Go to the implementation. And I'm going to skip over some of the code that we create by default for you to allow it to fill in more information for your application.

And I'm going to quickly add an implementation for each of these actions. And what it's going to do here is it's going to create a UI alert view. So UI alert view is just very similar to NS alert on AppKit. It allows you to create an alert with a title, a message, and some buttons. So we're just going to have an okay button.

Now if I go back over to Interface Builder, we can easily hook up this button is going to be our view controller. You can see here it's tiny font. The My App view controller is the actual files owner. If we click on the button and select the button connections, a key difference here is instead of having one target action, we have multiple potential events. So multiple potential actions that you can hook up for a given button.

Things like touch down, touch down repeat, touch drag, touch drag inside, outside. So we can just go ahead and drag from the touch up inside over to our files owner and let go. And we can see that we have the three different method signatures we had. But we can also have multiple different targets that you can have. So I can repeat this action and hook it up again to the other methods. And I can repeat it again.

And if we take a look at it in the button connections here, we see that in very tiny font, you have three different hookups for each of the target actions. So I should be able to go back in the X code and compile and run the application. And we'll start in the simulator.

I can click on Hello World, and it will throw up three different alerts, one after another. And the way the user interface works is that you click one, and the others then pop back up. This is a quick and easy way to see how an application is built and works. OK, let's go back to slides.

So that was a quick demo of the application architecture and how it works. Let's move on to drawing. So what are we going to cover in drawing? Well, first of all, we're going to talk a little bit about core animation. We're going to talk about drawing, actually, and some views. And then we're going to discuss animations. So let's jump right into it and start talking about core animation.

How does Core Animation work with NSViews inside of AppKit? Well, NSView optionally allows a Core Animation layer to back it. and you have to opt into it. So in other words, you have to do view, set wants layer, yes, to get a layer backing for your view. The layer can also be directly set, and there's a method, viewSetLayer, to custom set a layer.

So you may have a CALayer subclass that does some custom stuff you want, and you want to interact with the view and be the view's contents, so you call viewSetLayer to do that. You can also take that views layer and add custom sub layers to it and work with the layer hierarchy directly and not the NS view hierarchy if so you choose.

So how does this work with UIView inside of UIKit? Well, UIView always has a core animation CA layer for every view you see. In essence, you can think of the view's contents as the actual layer. So if you take a look at this little screenshot here, this is a UI image view. And you can sort of think of it as the CA layer is kind of backing the view. It's always there, and it is the contents for the view.

So a little bit more about UIView and how it interacts with the CAA layer. Well, the layer property is read only, which is different from MapKit, which then begs the question of, well, how do you actually customize it? And the way you do that is you would subclass UIView and override the class method, layer class, to provide your custom layer class subclass.

Some interesting notes. Well, the UI view is always the CA layers delegate. You probably don't want to change that. That will mess up things like drawing. But you can also take advantage of it and subclasses can optionally implement CA layer delegate methods if they need to. Another note is layer properties are directly reflected in the view. So if you change something like the frame on the actual view, it's actually changing the frame in the layer itself and vice versa. Other properties that do this are like the background color.

just like in AppKit, you can go ahead and directly add CA layers to the sublayer of the layer itself and not interact with the UI view hierarchy, if so you choose. Some notes about UIView and the frame and bounds. Well, the origin for the view is always the top left.

So if you look at this little screenshot of Safari, the origin of the web view is always that top left. What's that mean? Well, UIView doesn't have an isFlip property. But a special warning, if you create a custom CG context for some reason, the origin is still the bottom left, which is the same on the desktop if you're creating a custom CG context.

CG geometry and UI kit. What does this mean? UI kit went ahead and did what core animation did by exposing core graphics geometric types. In English that basically means that we use CG rect instead of NS rect. We use CG point instead of NS point. But then how do you convert these to common things like strings? We provide a custom header, uigeometry.h, that allows you to convert those things to common other types like NSString from C. There's a category on NS value and NSCoder to encode and read the values for CG geometric types.

Speaking of which, so here's a quick coding tip. UIKit is designed to work well with Xcode code completion. Now what does this mean? We took the time to make sure that all enums, function names, and classes share a common prefix when it's necessary. For example, in that last little bit that we saw, if you type in a string from and type escape, then you're going to see all the things that start with that prefix.

So it's very easy to not have to remember a bunch of methods and names and just instead remember a common prefix. So you type in a string from, see a huge list, arrow down to what you want, and hit enter. And you get in your code. Very fast and easy.

So we just discussed Core Animation. Let's talk a little bit more about drawing and views and how they work together. First, a little history on how it works with AppKit. In AppKit, if you call set needs display, it's going to redraw all the contents from that region that needs to display and everything below it. In this images, you can actually lock focus on this image and draw into it.

Overlapping sibling views are okay on Leopard and higher. Now inside of UIKit with UIView. Well, UIKit caches the resulting image from DrawRect. Overlapping sibling views are also okay. And similar in AppKit, you would use ordering to basically have one be appearing in front of another if they are siblings.

All the views, since the UI kit is caching the image from DrawRect, where actual core animation is, the views are composited together in the end to generate the final image you see on screen. And I'll discuss a little bit more on this in a bit. A little bit more on drawing. Well, drawing is available on UIKit with familiar classes that you're probably already going to easily be able to move over and start using. UI image is there, and it's a very lightweight and immutable object.

Simple things to draw the image like draw at point. Now, it's immutable, so you can't actually lock focus and draw into it. We do have methods and ways of creating a bitmap image context to draw into an image context. And I recommend reading the documentation or contacting us later for more information.

UI string drawing, we have to have a way of drawing strings. There's a special category on strings I like to do common string drawing operations. How do you specify what font to draw with? We have a UI font object, probably just what you would expect. There's a UIGraphics.h which does simple graphic things like UIRECTFILL and UIRECFRAME and whatnot.

So UIView and redrawing. Requesting a parent or an overlapping sibling will not redisplay the children. says, "The reverse is also true. Redrawing a non-opaque child will not redraw the parent." Now, both those statements are a little confusing. So here's an example screenshot. If you're going to redraw that button there, like if you want the background color to be something else, any call set needs a splant to redraw it. That will not redraw that label view that's on it. The label view already has its contents drawn and cached, and there's no need for it to redraw.

So that begs the question of core animation and redrawing and how does it actually work? So you have that view there, that basic button cell, and it was the view that's redrawn. So what happens is that view's contents, which was redrawn, is taken and added to the other two subviews, which weren't redrawn, and they're composited together to generate a final result. It's very simple.

drawing and performance. Well, first of all, I have to explain what does expensive mean. And expensive means it takes more time, uses more CPU, uses more battery life, et cetera. Overriding draw rect isn't necessarily needed in all cases. If you take a regular UI view, you can use it for a container as something to hold other views and place them where you need them.

And by not overriding draw rect, we have special optimizations we did in UIKit to make it very fast to have such a view exist. So it's very cheap to have a plain view and something to be aware of. It's also very cheap to set the background color because doing a solid fill is very simplistic.

Now, non-opaque views are expensive. So if you have a view which has something that looks partially transparent, it's going to be an expensive view. So if your view looks opaque, you should strive to make it be opaque. So if you have a label which is on a white background, don't make the label have a transparent background.

Instead, make it actually have a white background color and be opaque for performance reasons. Of course, if you have an alpha value that's less than 1.0 and you really need that, well, it has to be non-opaque and therefore it has to be a little bit more expensive. For more information, I highly recommend attending Optimizing Performance in iPhone Applications in Presidio Thursday at 3.30 p.m.

So we just took a second to discuss drawing and views. Now let's take a little bit of time to talk about animations. How do you do animations inside of AppKit? Well, NSView implements NSAnimatablePropertyContainer to do animations. And this is something new to Leopard. There's an animator proxy object which is used to animate properties. The animations can optionally be done by core animation if you're using CLA or back views. In addition, there's a NSAnimationContext that allows you to do things like control the grouping and the duration.

So here's a little code snippet, which you may or may not be familiar with because it's a new Leopard feature. You do NSAnimationContext, begin a grouping, grab that current context, set some properties like the duration, here it's setting it to two seconds, and then you're going to set the frame to be some new frame using the animator proxy object. So the view.animator.frame is set to a new frame. And after the two seconds, the animation would complete. So something as simple as animating a button is really to do.

UI view and animations. So UI view essentially has a mode that -- or a way of putting it into an animation mode. And once you change any animatable property, it will automatically be animated for you. You don't actually have to go through an animator proxy call to do it.

So here's some example code. UI view begin animations. And the begin animations actually takes a parameter that lets you identify the animation for later reasons. And an optional context so you can refer to it. And the reason it does this is there are other things behind the scenes you can set to receive when the animation has ended and do certain other operations like chaining animations together.

There's another class method, set animation duration, and there's other ones to control other animation things like the curves. Here it sets it for two seconds. Then you just set the property. So the view.frame is set to the new frame. And in this case, if you're doing that for the button, the button will go ahead and animate in two seconds. Very simple and easy to do. So some tips and tricks for doing animations.

Well, UIView is going to always use core animation. UIView animates by not calling drawrect along each step of the animation. So instead, it's just taking the views where it has the cache contents and recompositing them again and again as needed to generate the animation on screen. Animating in this way is very fast. Animating using drawrect and drawrect in each call is very slow.

So some special considerations that you have to take when you're doing animations. If they're changing the frame size, then the contents of the frame may need to stretch or grow or potentially redraw. And we have a UI view content mode property, which I recommend looking up in the documentation for more information on how to control that. In addition, session 446, how do I do that? Tips and tricks for iPhone application development. And Friday at 1030, we'll cover more about doing animations. inside of UIKit.

So views and controls. We just finished talking about drawing. And now let's move on to talking about some views and controls. First, we're going to discuss some common views. Then we're going to talk a little bit about scroll views. And finally, we're going to talk a bit about table views. Let's jump right into it and start talking about some common views.

So some common views and controls in AppKit and the counterparts for UIKit. We have buttons, sliders, text fields, search fields, the UI search field, or sorry, it's a UI search bar instead of a UI search field. So sometimes the names of things change a little bit. You have progress indicators. Now in AppKit, a progress indicator has two different styles. It has the bar style and the spinny style.

The spinny style inside of UIKit is a special subclass called the UI activity in the care of you. The NS button inside of App Kit has a checkbox style. Inside of UI Kit, we don't have checkboxes, but we do have UI switches that let you do that on and off mode and work like a checkbox.

NSDatePicker, well, the NSDatePicker looks different inside UIKit as the UIDatePicker, and it's the big swirly wheels that you've probably seen and used. NSPopupButton, there aren't any popup buttons on the iPhone. Instead, you can use the UIPickerView to do a popup type of style control. The PickerView also lets you do more things instead of just picking one item from the list. It lets you have multiple different columns, so you could have one column and another column and create combinations of results.

So we briefly talked about some common views. Let's discuss scroll views. First of all, how do scroll views work inside of AppKit? Here's a quick screenshot of the bookmarks table view inside a Safari. So the scroll view there, let's say it has a frame of width of 400 and a height of 400 for simplicity. It has sub views like the scroller on the side and the header up at the top.

In addition, it has the table view inside of it. Now, the table view's frame is a lot larger than the actual scroll view's frame. So its height is like 600, and it would exceed the height of what you're seeing. So how is it clipping it? Well, probably most of you know that there's an NS Clip view that actually does the clipping. So it has its Y frame a little bit lower because it's below the table header. And it has a height of 400 to clip the height. It has a bounds Y offset. to control the origin of the contents that you're seeing.

So how does clipping work with a UI view inside a UI kit? Essentially, any UI view can become a clip view. So here's a basic view, this turquoise-ish rectangle view. If you go ahead and see the default property for clips to bounds is set to no, which means that if you add two sub views, they won't be clipped. They can appear outside the bounds of that view.

If you set clips to balance to be yes, it will start clipping those other views. So UI scroll view by default has clips to balance set to yes to clip out content that you don't want to see. So taking a look at UI Scroll View. So here's a typical one. The frame, let's say for simplicity's sake, it's like a width of 200 and a height of 400. It really wouldn't be that because that's not the actual screen size.

Inside of it, the scroll view will have a content size which is higher, like 400, than what you're seeing. The way that you control the content offset is just like in its clip view. You set the bounds.origin, the Y, to something like 50 to control what you're seeing. And it's clipping the height with only a height of 400. So to make it easy to control the offset of what you're seeing, there's a property called the content offset that basically mimics that bounds.origin. So working with a scroll view.

The way you would work with a scroll view is you would go ahead and directly subclass UI scroll view. and the rest of the team at UITableView do this. And they go ahead and manage when the actual content changes and do special things like bring table cells into view. You can go ahead and add subviews directly to it. One difference is you don't actually have a document view property.

Now, when you have a scroll view, and let's say it has a button on it, there's a dilemma which is not present inside of AppKit. If you have that button and you touch on it inside of a scroll view, well, is it going to actually scroll when you move your finger? Or when you hit the button with your finger, is it going to track that button? Or in other words, a UI control? So what should it do? It's a dilemma, and we need a way of solving that.

The way you do this is we have a set of APIs on UI School View to control that behavior. Here they are, and I'm going to briefly talk about them. There's delays content touches to delay the touches to the actual view. You can't cancel content touches, and we'll describe a little bit about cancellation in a bit.

There's some methods on UI Scroll View that you can override. Touches should begin with an event in a content view, and touches should cancel in content view. I'm not really going to cover these, but it's important to be aware of that dilemma. For more information, I recommend attending How Do I Do That? Tips and Tricks for iPhone Application Development, Friday at 10:30 a.m.

So we just discussed scroll views. Let's move on and talk a little bit about table views. First of all, NS Table View compared to UI Table View. We'll both have a data source, both have a delegate, both represent rows of data, but the app kit NS Table View can have multiple different columns, which you're probably familiar with.

The UI Table View only allows one column, and although it only allows one column, you could mock up multiple columns by adding separate sub views that make it look like it has multiple columns. supports sectioning data so it allows you to have different sections of data that you can expand and collapse. The UI table view by default always supports sectioning of data.

And we'll talk a little bit more about how it works with UI table view in a second. Inside of App Kit, you can have multiple selection in tables, but inside of UI Kit, you really only have one selection at a time. Selection is more of a temporary thing on the iPhone.

So if you go ahead and select a row and let go, it will probably do some action like slide another view into screen, and then after the view goes away, the selection will go away. So the selection is very temporary. Inside of AppKit, you're probably used to using NSLs to do the drawing. Well, inside of UIKit, we went ahead and used UI views to actually do the full drawing.

So what does a UI table view look like? Here's one style which you're probably familiar with and have seen. It's what we call the UI table view style plane. It's your basic contact list with multiple sections there. In addition, we provide out of the box for you a UI table view style grouped that allows that group style.

So it's taking the sections and combining them together with different little button looking like rows. These styles can be set in the initializer. I'm not going to cover that. It's easy to use. You just allocate the table with the particular style you're interested in and that's the way you get it.

Some more details on how the table is laid out. Again, the table is broken into multiple sections. So you can see that the sections could optionally have a header. Inside of each row is a UI table view cell. It's a full-fledged view. So that view can have subviews. So by default, we provide a UI image subview inside of it, and you can easily set that image by doing cell.image equals some UI image that you load.

There's also a label subview. So you can also easily change that label text by doing cell.text equals some text. Very easy to use. Now, these views are lazily created and added to the view hierarchy, so you don't have to use them at all. And if you don't use them, there's no cost to having them there.

The table view in sections. So you've seen that the table view is broken into multiple sections. So the first thing it's going to ask the data source is, well, how many sections do I have? So it says data source, number of sections in table view, and then you would return the sections. Now, a common programming error is to say, oh, I don't want any sections, so I return zero. Well, you should return at least one because you always need one section. By default, if you don't implement this, you will get one section.

So how is a row specified? Because you've seen that we have rows inside of a section, and we need a way of identifying that. So the way we did it is we use NSIndexPath to represent the section and the row, and we add a category to make it easy to use that. So this is the category that UI TableView applies to NSIndexPath. There's a simple initializer, index path for row and section, and there are some properties on it to access the section and the row.

Behind the scenes, all this is really doing is it's creating an index path with two indexes in it. The first index is going to be the section, and the next one is going to be the row. But it's very easy to just use the initializer and the properties that we provided.

requires data source methods. You're probably familiar with NS table view and AppKit. You have to implement certain methods to get data. The same is the case on the phone. And of course, you need to know how many rows are in a section. So it's very simple. Table view, number of rows in section, and you return your row count.

Now, the cells are the next piece of information you need to know. So comparing the app kit to the UI kit cells. Well, a cell, of course, is used for the row column inside of app kit and NS table view. Essentially what the NS table view does is it takes the same cell and it just kind of stamps it out along each row to get the desired result. The cell itself is not a view. It just descends from in its object and does the drawing for you. Now in UIKit, it also uses cells. And there is one cell, in particular a UITableView cell, for each visible row that you see on screen.

The actual cell is a full-fledged view. So it goes ahead and descends from UIView. And again, you really only have the views for what you see on screen. So there are not cells for what's not on screen because that would not be good for performance. So that begs the question of, well, how do you load those cells and load them to what you see on screen? And then what is the concept of reusing those cells for performance? So here's an example screenshot. Let's say that you take your finger and you want to go ahead and scroll this view up. So old cells are going to move off screen in the gray area above. And the new cells are going to move from down below into that bluish area below.

Taking a look at that, well, those top non-visible table view cells, the table view is going to just take them and remove them from the super view. It's going to add them to a reuse queue inside of itself. Then the data source can go and grab one of those cells, if there's one available, and give it back to the table view for it to go ahead and reuse them.

So in essence, the table view data source is what returns a cell. This is a little different from NS table view because the data source is the thing that actually returns you the cell. And it's going to either reuse one or it's going to create another one. takes a look at some of the code to actually go ahead and create it and do it. TableView, cell for row at index path. So again, we had spoken earlier about the way to uniquely identify a section and a row is with an index path. So it's passed into you.

First, you should try and find a cell you can reuse. And the way you do that is you ask the table view, dequeue reusable cell with identifier. So you're saying, hey, I have this identifier for a type of cell. Is it already there and can I reuse it? If it didn't because there's none there, it might be the first time.

Then you go ahead and use UI table view, cell alloc init with frame. And now the initializer has an additional parameter called the reuse identifier. So this lets you designate a cell with a identifier. And then you can designate a type of cell that you can reuse later on. After that, you'll set common properties. If it was a reused cell, you'll just be redrawing and reoverriding them.

So some key points about it, as we said, it's a full-fledged view. Things you probably don't want to do, we don't want to override draw rect on the UI table view cell. Instead, we have those default views that you can use with properties that we allow you to set, like the image and the text. You can actually add other subviews to it that do the specific drawing that you want.

And something that you really want to do for performance, you always want to reuse cells. Otherwise, your scoring performance in your application will not be good. For more information, I recommend attending Mastering iPhone Table Views Friday at 9:00 AM. And what they're going to cover is more advanced things, like doing the animations to insert and delete cells, doing the animations to show the delete buttons on the side, and whatnot.

So text views, fields, and labels. Well, the iPhone has typical text entry as you've seen. There's a basic UI label class to provide simple read-only text. There's a UI text view, which is a big, huge text area. A UI text field to do editable text entry. They're all fairly easy to use and straightforward. And I recommend attending text input on the iPhone, Russian Hill, Wednesday at 5 p.m. for more information.

is the founder of Drupal, and he's the founder of Windows. We just discussed views and controls. Let's move on and talk about some events. So first we'll discuss Windows, then discuss respond or event handling, and finally control event handling. Let's jump right into it with Windows. In both AppKit and UIKit, all events are filtered through the window through a send event method.

AppKit uses NSEvent, UIKit uses UIEvent. The actual window in AppKit, again, is just a responder inside of AppKit, but in UIKit, it's actually a full-fledged view. So this means that you can do things like add subviews, there's a hidden property on the view to make a window be visible, et cetera.

Now, you've seen on the phone, and there aren't ways to resize windows, there is no close buttons, and hence, there's actually no delegate for the UI window. In AppKit, the main reason that we have the delegate is for all those operations for you to control and override. There is a need for that inside of UIKit.

The UI window doesn't have the concept of make key and order front. Instead, basically the window is a view, and you just make that view not be hidden to make it actually be visible. You can control the window level to actually do ordering. And we do have one simple method that lets you do it all at once. And I recommend using and reading the UIV documentation for information on that. Of course, the biggest difference in Windows is that, well, the UI window deals with touches instead of mouse events.

We briefly talked about Windows. Let's go ahead and talk about responder event handling, particularly how to do it inside of AppKit, and then we'll talk about how to do it inside of UIKit. In AppKit, you're probably familiar with two different ways to do dragging event processing. The first way we call the three method approach. So you would override mouse down, probably set up some state or whatnot. Override mouse, drag, do some logic like drawing lines or whatever you want to do. And then override mouse up to stop your logic.

There's also the mouse tracking loop approach. So you would override mouse down, loop, go to NS application, extract events that you're interested in, and then stop looping once you do something like process and mouse up. That's all done within an override of mouse down. Something that does this is like NS table view, which overrides that and passes the tracking onto the cell itself. We don't recommend doing this approach inside of UIKit, and we'll discuss the proper way to do it in just a minute. First, we need to have a basic understanding of what a touch is.

If you take your finger down and put it on the phone, you're going to get a touch began. So the phase began. If you move it, you're going to go ahead and get a touch moved. So the same touch has its phase and location changed to being moved. If you remove your finger from the screen, you're going to get a touch ended.

Now, multiple touches. So let's say you take two fingers and stick them down. You're going to get two touch begans. Overall, you have all touches of two. If you put a third finger down, well, those two touches, they stay the same instance, and they just change their phase to be stationary. The third touch, you get a touch began.

If you move one of those first ones, well, it gets a touch moved and the other stays stationary as their phase. Then you remove all three fingers at once, and all at once you get three touch-ended. It's important to note that multi-touch is opt-in and you have to set a property view.multipletouchenabled to get multiple touches. If you don't do this and you're confused as to why you're not getting multiple touches, this is the reason why.

So touches and cancellation. Cancellation is a new thing that's on the iPhone that you have to worry about. Take your finger and you put it down and you get a touch began. You get your touch moved. Now let's say something like a phone call comes up. Well, you have to get a touch canceled to cancel that touch event. We'll talk a little bit more about this later and how to deal with it.

So now that we know what touches are, how do you actually handle events with UI Responder? We recommend you always use that three method approach and implement the cancellation. So it's really more of a four method approach. And the four methods are touches began with event, touches moved with event, touches ended with event, and of course, touches canceled with event. It's passing in a set of touches that cause that thing to happen, and then an event that has some more information, which we will describe in a second.

So how is a UI event and a UI touch represented and related? So the UI touch is actually an instance in a class that you interact with. The UI event itself has a timestamp for when it happened. The event contains a touch. Well, you could have multiple touches, so it contains one or other touches. Inside of each touch is a timestamp.

But more importantly, there's a location and a previous location for that touch. An important difference from inside of AppKit is the location is actually in the touch and not in the event itself. The touch also has other information like the view that it occurred in and the window that the view is in. And it has a phase. So the phase is something like began, moved, ended, etc.

So let's take a look at one of those methods and follow it along just a little bit. First of all, touchesBegin passes in a set of touches that actually made that touchesBegin happen. Inside of each touch is where you would find the location. The event itself has a reference to all touches. So of course, all touches is going to reference those other touches that you already got, but there may be other ones that were stationary, and this is the way you would access those ones.

Some more notes about UI Event and UI Touch. Well, how do you actually get touches for a UI Event? You can use all touches. You can use touches for view and some other methods which we briefly discussed before. The important thing is that the UI touch contains the actual point and you access it via location and view.

The touch instances actually remain the same. So they are the thing that has their properties change, like the location, the previous location, and the phase. Those things, those properties change, but the instance does not change itself. Another thing to note is the responder chain is slightly different. So what does this mean? Well, inside of AppKit, you can call setNextResponder to actually change the responder and it's saved for you.

Inside of UIKit, there is no setter for the responder. Instead, you would have to override the next responder. By default, it just goes up the view hierarchy chain and also works with view controllers a little bit. For more information on touches, I recommend session 380, iPhone multi-touch events and gestures, Wednesday at 3.30 in Mission.

So we just discussed responder event handling. Let's move on and talk about controls and event handling. How do you handle events with UI control? Well, first of all, control tracks the first touch and ignores the others. Now, this is important for things like control subclasses, buttons, sliders and switches and whatnot. And if you think about it, it makes sense.

If you take one finger and put in a button, then you take another finger and put in a button and you release that second finger, well, you're still holding your first finger down and you don't want that other finger to actually do the action. You don't want to do the action until your first finger is removed from the screen. So control is good to track the first touch that happened and that's what it's designed for. So it disables multi-touch by calling control multiple touch enabled equals no, which is actually the default for a UI view.

So how do you actually override and subclass a UI control? Well, you're probably familiar with how to do it inside of NSLs, and it's very similar. There's a set of methods on UI control that you can override. Begin tracking with touch with event. Continue tracking with touch with event. End tracking with touch with event. And of course, cancellation you also have to consider and probably stop whatever action you were doing. So cancel tracking with event.

So UI control and target action. As we already know, you can hook up usually one target and one action per control inside of AppKit. But UIKit is different. You can have multiple different targets and multiple different actions like we saw at the demo at the beginning. Now, how do you represent those? Well, there's a bit set called UI Control Events that lets you control the different events you want to actually handle.

So there's ones like UI Control Event Touchdown, UI Control Event Touch Up Inside, et cetera. There's lots of these. Also notice that they all have that common prefix I was talking about before. So inside of Xcode, you could type UI Control Event, hit escape, and see a list of all of them that are available. Very easy to do, and you don't have to memorize them all the time. all.

So now you know how to actually get the actions and what are available. How do you actually register a target? Well, there's a simple method. Add target, action, four control events. So you can have an orbit set of the actual control events you want to handle with your target and the selector you want to have called.

Again, it's not a one-to-one relationship, so you can call this multiple times again and again with different targets and different actions. Thank you. There are three different signatures as we saw before. There's one signature which doesn't have any parameters. A signature which has a sender just like inside of AppKit. And then a signature which has the sender and the UI event that made it happen.

You get to choose. So in summary, we talked a bit about application architecture. We talked a bit about views and controls. Then we went on and talked about drawing. And finally, we also talked about events. For more information, come find us in the labs, the iPhone Controls, Views, and Animation Lab, the iPhone Multitouch and Events and Gestures Lab, the iPhone View Controllers Lab, and get more information and help with your applications. For more information, you can contact Derek Horn, our Application Frameworks Evangelist, and look at our excellent documentation. Go to the iPhone Dev Center.