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: wwdc2001-702
$eventId
ID of event: wwdc2001
$eventContentId
ID of session without event part: 702
$eventShortId
Shortened ID of event: wwdc01
$year
Year of session: 2001
$extension
Extension of original filename: mov
$filenameAlmostEvery
Filename from "(Almost) Every..." gist: ...

WWDC01 • Session 702

Interface Builder

Development Tools • 57:41

Interface Builder is Apple's graphical editor for designing user interfaces for Cocoa and Carbon applications. Learn how Interface Builder allows you to easily access underlying framework concepts like Cocoa targets and actions and the new Carbon event model. This session describes the features in Interface Builder that make it easy to manage virtually every aspect of creating a well designed user interface that adheres to the Aqua user interface guidelines.

Speakers: Henri Lamiraux, Scott Herz

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. So, down below all the lights, how many people were here for the Project Builder session? Just raise your hands. Excellent, so more than half of you. Development tools are one of the most important aspects of building the new operating system and making successful applications. And in that direction, I want to just introduce very rapidly Henri Lamiraux, manager of the Interface Builders group. And he's going to tell you all about our world class leading Aqua UI design tool. Thank you. Right on the podium. Good afternoon.

I want to start by pointing out that today we have a wide audience here. We have developer which started to use Interface Builder many years ago with Next Steps, then Open Steps, and now with Cocoa. We have also developer that just starting to use Interface Builder or are thinking about using Cocoa and use Interface Builder. We also have Carbon developer now who can use Interface Builder. So as you can see, a wide audience of developers with different needs, different interests.

So when we think about that, we decided to organize our talk around several topics. We want first to answer some of the frequently asked questions, questions that are coming over and over on the default mailing list. We want to show you the new features we've added to Interface Builder this year. We want to give you some tips on how to better use Interface Builder and also give you some demos.

So this is the roadmap I'm going to be following today. I'm going to first introduce quickly what is Interface Builder and then go-- IB for short. I'll be using the word IB sometimes for this Interface Builder. I will go then through the three steps it takes to develop an application using Interface Builder. First, you have to lay out your user interface. Then you have to connect your user interface to your code. And then you have to load the user interface in your application. I'm going to go through some tips and tricks, talk about and talk about our update schedule.

So let's start with what is Interface Builder. Interface Builder is Apple's user interface builder tool. We have one tool at Apple that covers all of our frameworks. This is Interface Builder. Interface Builder has been tuned to create Aqua compliant user interfaces for both Cocoa and Carbon. And although Interface Builder originally was a Cocoa tool, we now support Carbon as a first class citizen. Both Cocoa and Carbon are fully supported by Interface Builder. We're spending as much time on both frameworks to support both frameworks.

So Interface Builder, it's a Cocoa application running on Mac OS X. With Interface Builder you create what we call Nib files. Interface Builder does not generate code. We don't generate Objective C code or Java code. We generate what you call a Nib file that contains the description of your user interface.

I show here two different Nib files, a Cocoa Nib file and a Carbon Nib file. Although they have the same structure internally, they are quite different and you cannot use a Cocoa Nib in a Carbon application or a Carbon Nib in a Cocoa application. A Cocoa Nib is archive objects, archive Cocoa objects.

It can be the app kit objects or it can be also your own objects. So it's an archive of objects. The Carbon Nib is more of a description of your user interface. Carbon is not an object oriented framework. So the Carbon NIPs are more of a template for your user interface.

Also I want to point out that in a Cocoa Nib you have more than simply objects. You also have the connection between those objects. How those objects interact between each other. As you can see the Cocoa Nib and Carbon Nib are a little bit different. Also the Carbon NIPs are XML based while the Cocoa NIPs are still using a binary format.

So from a Cocoa nib, you can create a Cocoa application either in Objective-C or in Java. Because we don't generate code, the language you use to develop your application, I won't say we don't care, but it's not important for us. You can also create a Java client web object application, and there are several sessions this week that show you how to use Interface Builder for using web objects.

With the Carbon Nib you can create a Carbon application and you can target both Mac OS X and Mac OS 9. The code that allows us to read a Nib file and recreate your user interface is available in both Mac OS X and Mac OS 9. I should have said 8 and 9 because in fact we support also 8 and 6. So you can target both platforms. You have to do your development on 10 but you can target both environments.

So let's start with how do we-- the building tool, the thing you want to do first to be able to layout your user interface. You want to put button in a window, you want to edit your menus, and things like that. So how do you do that? We have a wide variety of layout facilities. And the first one I want to talk about is what we call guides.

If you use the interface builder several years ago, there was a feature called the grid. And we discovered that it was not working very, very well. And it was not working very well also with Aqua, because it was hard to align object with Aqua on the grid. So we replaced the grid by something we call guides. We think it's a much faster way to align object-- much faster and intuitive way to align objects. And we have two types of guides. We have what we call the Aqua guides, and what we call the user guides.

So let's start with the Aqua guides. The Aqua guides implement the Aqua layout guidelines. That means that this is a way for you to be sure that you are putting your UI at the right place in your window. So in picture number one here, I am putting a button-- I'm dragging a button inside the window.

And as I move this button close to the edge of the window, lines will show up and show you what is the right distance for this button to this window. You can put it anywhere you want, but this is we show you where it would be the best place for this button. And as you move closer to those guides, the button will snap to those lines. In picture number two, I'm moving a second button close to the first button. And same thing, we tell you what is the right distance between the second button and the first button.

The user guides are similar to the Aqua guides except that you can do whatever you want. You can put them anywhere you want in a window. You have vertical guides, horizontal guides. You can put as many as you want. You define them. They are saved with a nib file so the next time you open the nib, those guides will be loaded.

And something here, when you move an object, a UI element close to those lines, they will snap to those guides. This is useful, for example, to create templates. You want all your different dialogues to look the same and you want to be able to put guides there to have a way to have your UI looking the same.

Then we have what we call layout track, which is not a Cocoa nor a Carbon notion. It is a pure IB notion. There is a difference between Cocoa and Carbon, how they are drawing UI elements. On the Cocoa, everything is drawn inside the frame. The shadow of the Aqua buttons, etc. are drawn inside the frame. On the Carbon side, the shadow is sometimes drawn outside of the control bounds of the control.

The Aqua guidelines give you some numbers, saying a button should be 20 pixels high. The layout track matches those Aqua guidelines. It is a visual bounding box of an object. You can turn them on and off by using command L. In this image, it draws those red borders around your object and also shows you the baseline if your object has text. This is very handy to see where a control hangs because of the anti-aliasing of Aqua and the shadow. So sometimes it's hard to figure out where your control really ends.

We have also distance measurement. This is a way to measure distance between two objects or between an object and its container. So the way you do use distance measurement is by selecting an object. And as you press the Option key, and as you move your mouse above other objects, we show you those lines with a distance. Very handy feature to figure out what is the distance between two buttons or things like that.

We have also a full layout menu with plenty of options. Usually those menu items act on a group of objects. So you can align all the edge of the left edge of those objects or the right edges. You can make colors. You can make rows. You can change the ordering of objects, send them to the back, move them to the front.

Very similar to a program. And also you can make objects the same size or make them fit to the content of this object. So different options there. We have an alignment panel which has some of the same functionalities as the layout menu plus some other ones, just a different way to present those options. We also have... Can you change the clock? It's still 75. Thank you.

I won't stay here all day long. We also have a test mode, which is not really a layout facility, but it's a way to see your application like it would be at runtime. I'm sure you've all seen the demonstration during the keynote Monday, where we were able to build a full iMovie-like application and run it inside Interface Builder without really using PBE or compiling anything. Just bringing your code inside Interface Builder and be able to create a full application and test it within Interface Builder. Test mode will work for both Cocoa and Carbon. Containers.

So Interface Builder enforce the notion of a view hierarchy. Cocoa has a notion of a view, the building block of the user interface. And view, as a super view, we can have sub views. In the original toolbox, Mac toolbox, there was no notion of embedding except a button was inside the window, but that was it, there was no notion of embedding.

With Carbon now, we have also embedding, an object can be embedded into a group box. And Interface Builder maintains this hierarchy of UI elements. So if you have a group box and you want to put a button inside this group box, you have to put it really inside the box, not just on top of the box.

And to do that, right now you have to double click on the group box, and you get this ring around the group box that says, the editor on this group box is open. And now you can drag the object inside. And as you move the box, everything inside the box will move along with your box.

Also, we do clipping correctly and everything like that. So this is a very important notion if you are using tab view, group box, you need to open the editor before you can drag something inside those containers. So I have to bring Scott Herz on stage. He's going to show you some of the layout facilities. OK. My on.

So the first thing I'm going to do is I'm going to give just a tiny little tour of IB since I have a feeling a few of you haven't even opened the application. This is our starting point dialogue. You can see that you can make Cocoa applications and you can also make Carbon applications. I'm going to go ahead and make a Cocoa one, although everything I'm going to show applies to Carbon as well.

This is our design window. You can drag widgets from our palette over here onto it. And then you can change their attributes, their size, their connections, all kinds of things using this inspector palette over here or info palette, sorry. We have a document window here which contains our top level objects. We have a window and a main menu. And then there's also the files owner and first responder for Cocoa which we'll talk about later.

So now let's talk a little bit about some of the new layout facilities we have. I'm going to go over it pretty quick since Henri covered it fairly well. I'm going to drag a button out and these little blue lines appear and it'll snap to where the human interface guidelines say that button should, where that button should be.

I don't know if anybody saw, there was an AquaTalk earlier or if it's going to be. There's this great slide where there's this dialogue all laid out and there's something like 40 little numbers of where everything should be lined up. And when they came to us with those guidelines we were pretty spooked by the whole thing.

So what we did is we compiled all those numbers into the application so it knows, for example, and I'm going to show the measurement lines by holding the option key down, that a button should be 20 pixels from the right and 20 pixels from the bottom. So now I'll drag another one out and just like Henri showed in his slides, it'll snap and it knows that it's 12 pixels from here and then also 20 pixels from the bottom.

An interesting note with the measurement lines, if I hold the option key down, over the selected button, it shows which guides are selected. So that's the first thing that I wanted to show you. And then the second thing that I wanted to show you is that the measurement lines, if I hold the option key down over the selected button, it shows which guides are selected.

Apply to that widget. So we do more than that. We know how to do like tabs. Like for example, tabs can be all the way to the left or they can be over a little bit. We'll drag that down here. They know how far they should be above a button, which is completely different than how far a button should be from, say, a pop-up button.

I'm going to double click on this to open the editor. And Henri mentioned that you have to do that for containment. I'm happy to say that in a future version, this nonsense is all gone and you won't have to worry about that. And it'll work as it should have 11 years ago.

So I'll drag this out. One thing that we do is indention. This is really great for preferences dialogs and things like that where you have a header, then you have a lot of check boxes below. I'll drag out a radio button group. And as you can see, it knows that it should automatically align down there. I'll switch the tabs. I'm going to bring out a button.

And I'll make a matrix of buttons by holding down the Option key, something we hear asked a lot. How do I make a matrix? Well, you hold the Option key down and you just grow it. I'm going to turn on the layout rectangles and you can see here if I make this a little bit longer,

[Transcript missing]

So we've seen how to layout your user interface and all the facilities we have in Interface Builder to do that. Now let's talk about how do you connect your user interface to your code. You have a button, the user clicks on the button, you want something to happen.

So, in the layout facilities we didn't make any distinction between Cocoa and Carbon. They work the same way. There is no difference as far, except for the UI elements you have available on the pallet. There are no differences between Cocoa and Carbon as far as layout in Interface Builder. The same features.

When you come to how to connect your user interface to your code, this is different. Carbon and Cocoa are different frameworks. Carbon is a CPI procedural framework. Whether Cocoa is an object oriented framework and relies heavily on the dynamic feature of Objective C. So, totally different framework. Let's start with Carbon.

The thing you have to understand is that IB does not change the programming model of Carbon. If you know how to use Carbon today, you can use Interface Builder immediately. We don't invent a new way to program Carbon. This is just a better way to lay out your user interface and to package your user interface. It makes it easy to use the Carbon event model. We have some features in IB that make it easier for you to use the Carbon event model.

But you don't have to forget the Carbon API is the same API. There are two things you may want to do as a Carbon developer. You may want to get a reference on the UI element. And you want maybe also to get a pointer on the button or a text field. And you want also to react to some user action.

So let's first talk about getting a reference to a UI element. So what do you do in Interface Builder? You build your user interface. You bring one of those info window. And you can just assign control ID to controls or menu IDs to menu like you would do anywhere else. And in your code, call the appropriate API, the appropriate Carbon API, to get a reference to your control by calling getControlById or to a menu by calling getMenuReference, getMenuRef, or et cetera. So nothing very unusual.

To react to a user action, Carbon has this notion of a command ID now. You can assign a command ID to some UI elements, or you can assign a command ID to a menu item or to a control. And in your code, implement the event handler to process those commands. There is a talk right after this one about the event manager. And if you want to learn more about the event manager, stick around.

So as you see, nothing very unusual, just a new way to lay out your user interface and set up your user interface so you can connect your user interface to your code. So I'll bring back Scott on stage to show you some of those features. Did you miss me? Good. OK.

So I'm going to go back to our starting point dialogue. And this time I'm going to create a Carbon application. I'm not going to show you so much, not really going to show you any code. We'll let the Carbon folks do that in the next session. But I want to give you sort of a tour of when they talk about the control ID and where to put your HI commands, I want to show you where those are in Interface Builder. Once again, we have the same. We have a design window. We have a palette. All of your favorite Carbon widgets are represented here.

So I'm going to drag out a button. And as you can see, the guides work in Carbon just as well as they work in Cocoa. I'm going to bring up the inspector here. And I'm going to switch to the Control pane. And here's the signature that you would use by something like in Get Control by ID. You fill out the little struct.

You're going to type something in there. And you're going to remember it. And you're going to put it in that struct. And here's the HI command. So you've seen us do in demos past where we put quit. And it's automatically been sent to the nearest handler that listens to it. So what you would probably do is you would put some sort of command of your own working in there. And you'd listen to it in a window controller or something like that. That's all I have to show for that one. It's a quickie.

So, a quick demo on Carbon. As I said, there is a talk right here, right after this talk about Carbon Event Manager and you'll be able to learn more about how to use the Carbon Event Manager. Cocoa now. There are four important Cocoa ID concepts that you need to understand to be able to use IB and Cocoa.

Those four notions are the notion of outlet, target action, file donor, and first responder. Those are very important to understand because you have to use them. You can't just say, "Oh, I'm going to skip file donor. I don't want to know about this one." You have to understand all of them.

So let's start. So an outlet. An outlet is an instance variable that points to another object. It's just an instance variable. Just another fancy word for an instance variable. To point to another object, that means that an outlet cannot be an int or a float. It has to be a pointer to another object. Why do we call them an outlet? Because this is a special instance variable that you are not setting this value by code, by writing code. You're setting this value of this instance variable within Interface Builder.

By making a connection between an instance variable of a class and some other object, you can set the value of this outlet. So here I have a class foo that has two instance variables, a window and a button. And I can, in Interface Builder, set the value of this object within Interface Builder without writing any code.

So at one time, this object will have those values there. Target and action. Target is an object responsible for responding to a user's action. Just an object. The action is a method in this object that specifies what the object is to do. So a lot of objects in the app kit have two instance variables called target and action. NSControl and NSMenuItem have those kind of instance variables. Those two instance variables are like outlets. You can set them using Interface Builder. The first one, the target is a pointer to an object. You say, when I press this button, I want this object to do something.

And the action is, I want this object to do something. I want to execute this piece of code. So in this case, the target is a pointer to this object. And the action is a method within this object that's going to do something when you press the button. So the actions have a specific pattern. They do something with one parameter, which is a sender. In this case, the sender will be the button itself.

So as I say, what is the role of Interface Builder regarding outlets and target action? It's to graphically connect those outlets and those target actions together. All those connections are saved in a Nib file along with all your objects. And at runtime, all those connections are put back together, like if you were doing it by program, except you don't do any programming here. Outlets are set. Control, menu item are ready to trigger the appropriated code. This is what outlet action and target actions are.

Now, FileZoner and First Responder, the two big ones. If you look at a document window of Interface Builder, you see all those icons. And there are two important icons in there, which are the file owner and the first responder. And their name is grayed out because you can't change the name of those objects.

But those are not real objects in a Nib. They are just proxy objects. They are standing from some other object that are outside of the Nib file. Those objects are not instantiated with all the other objects that you have in your Nib file. In a Nib file you have a window, you have a menu, etc. Those objects are coming back to life when you load the Nib. But those two objects are not. They already exist before you started to load the Nib file. So they are just proxy objects.

The file owner, as I said, is an existing object. It's external to the Nib file. There is already an instance of this object somewhere in your application even before the Nib was loaded. And you're passing this object to the call that allows us to load the Nib file. In this case we are using loadNibName, passing the name of the Nib and passing this file's owner.

What's the role of this file owner? Its role is to channel messages between objects that are unarchived from the Nib and objects that are outside your application. Imagine your Nib has a little bubble of objects and if there was no file owner there would be no way to reach what's inside this bubble. You need some way to reach inside the Nib file when the Nib file is loaded and this object is the file owner.

First responder is also a proxy object. It's not instantiated in your Nib file. The first object, the first responder is more of a status given to an object than a real object. The definition is that it's the first object in the responder chain to respond to a message.

As I say, the files owner was a real object. The first responder is what is different object depending on the situation of your application, where your application is, what you have been doing with your application. So let's also explain what a responder chain is first. confused here. So let's explain first what the responder chain is. So I have a responder chain here which is not completely right. It's just for an example. It's a lot of missing objects in this responder chain, but it's just to show you how things work.

So I have an application. I have this application has one window, and inside this window I have a control, which here is a text field, and the user is typing in this text field. As the user types in the text field, he pulls down the menu and shows hide window.

So the hide window menu item was connected to the first responder. So the hide window message is sent, and it goes to the object that currently has the focus, which is the text field. The text field knows nothing about hide window, so it says--it passes to the next responder, which is the window. And the window says, yes, I know how to hide my window, so hide the window. So by connecting to the first responder, you're connecting to whatever object that are currently in the responder chain that can answer this message.

This is a very useful concept. The first responder is useful to connect an action to an unspecified instance of a target. You have 10 text fields in a window. You don't want to connect your cut, copy, paste menu item to every text field in your window. You just want to say, connect it to whatever text field has currently the focus.

And you connect it to the first responder. You can also use the first responder to connect an object to an object outside of your Nib file as long as this object is inside the target chain. We do use that for example for NS application which is never in a Nib, but you may want sometimes to connect a menu item to some action in your application.

A good way to do that might be to use the first responder to connect your menu item to the first responder and the application will get this message if nobody else is getting it. So now I bring Scott Herz back on stage to the big demo. This one's hard.

So the first thing I'm going to do is show you the application that we're going to build to demonstrate how to add an action to first responder and how to connect your interface to it. We're going to do it with this little application here. If you look on the window on the right, it's the front most window, which means that you could consider it to be the lowest object in the responder chain. So when I say toggle picture-- There's a message that we're going to, well there's an action rather, that we're going to add to first responder.

[Transcript missing]

There's a little bit of code that you need to see. This is our NS application subclass. All it's going to do is it's going to create two of our toggle controller classes. And those toggle controller classes are what create the window and handle messages that come to in front of it. So this is the header for the toggle controller. There's two things I want you to see here. We declare an outlet to what's going to be an NS image view called Picture Outlet.

This header file also implements our action called toggle picture action, or toggle picture. We have these two little blurbs here called IB outlet and IB action which actually sort of null out. They don't really do anything, but what that allows IB to do is look through your header and parse those, these outlets and actions in. We have two nibs, we have a main menu, and we have a toggle window. So let's first take a look at our window.

You saw this earlier. There's no picture in it right now because the code actually puts that in. What we want to do is we want to hook this window up to our toggle controller code. Before we can do that, we have to tell the nib what is a toggle controller. So we go to the classes pane here. We go to the classes menu and we say read files.

And what we can do is we can find our header file. So here it is, toggle controller. And we can parse it. And if you look down here, it's realized, oh, here's toggle controller. Not only that, but it's an NSWindowController. It's already figured out from the header what type of subclass it is. I'm going to click the little actions dealie here. And we can see that it's found our picture outlet. It's also found the window outlet that comes from NSWindowController.

And it's also found our toggle picture action and then another action show window that's also implemented by NSWindowController. So we've told the nib, hey, here's what a toggle controller is. So now we need to tell the nib that you're actually going to be loaded by a toggle controller. Your files owner is a toggle controller.

Right now it's just, it doesn't know, so it's just set to NSObject. If I scroll down, we can actually click the toggle controller here in the files owner attributes pane on the inspector. So now that we've told the Nib, hey, FileZoner is a toggle controller, we can go about making connections to it.

So I hold the Control key down and I drag from Files Owner. And the first one I'm going to do is our picture control. And you see how it highlights? It's going to bring up the connections inspector and here we go, here's the picture outlet. So I'll click that and I'll click connect.

Now we need to tell, now that we've put the picture control up, we've done sort of all the connections for our toggle controller, we need to go about and do the ones that NSWindowController wants. Namely, it wants to know what window it's supposed to be controlling. So I'll hold the control key down again, and this time I'm going to drag from FileZoner to the window. So if you look right here in the connection inspector, click on window, click connect.

So we've hooked all of our outlets up, but there's one thing we haven't done yet. We haven't inserted our toggle controller into the responder chain. So remember how Henri showed you the sort of the simplistic view of what the responder chain is? Well, there's one more little thing. If NSWindow can't respond to your action, it'll try what's called its delegate.

And that's how we're going to get into the responder chain. We're going to set our toggle controller to be the delegate of those windows. And how I do that is by holding the control key down again, go from window to files owner, and I can set its delegate. And I hit connect.

So that's done. I'm going to close that. Now let's take a look at our main menu nib. I'll open this up. So here's our main menu editor. Here's our toggle picture command. We want to make an action. We want to drag an action from our toggle picture to the first responder.

But out of the box, Interface Builder doesn't know anything about that action toggle picture, so we have to tell it again. So what we do is we go to the classes pane, and we go all the way to the top where first responder lives. Then we go up to the classes menu and I'm going to say add action. And I'm going to type toggle picture.

All these other ones that are in gray are sort of convenience ones that we know that a lot of other stuff implements and so we put those there for you just sort of for your convenience. But we have to add this one because like I said 11 years ago we had no idea somebody was going to make something called toggle picture. So we have to do it.

Now that we've added that to first responder we can drag a connection. So once again with the control key, drag it down to our first responder. So we want to set the menu items target to be toggle picture. So I hit connect. And if I've remembered my script, that's all we have to do. So I'm going to go here and I'm going to build it. I'll probably kill this one just to prove that I'm doing it. And we'll run it.

So here's our front most window. And oops, I forgot to hook something up. You put an uppercase T. What's that? You put uppercase T. Huh? You type toggle picture with uppercase T in the name. You were supposed to shout that out when I did that. You're not much of an audience. Uppercase T.

Ah, there we go. Yay. So the only thing we don't do is spell checking in the control-- in the connections inspector. Thank you. Those notions of outlets, target action, file zone, first responder are very important. File zone and first responder are difficult notions and they are quite unusual in this environment. They are difficult notions but they are very, very powerful and you can do anything you want with those two notions.

So look at them, practice, look at all of our code. It's very important to understand the notion of file zone and first responder to really be able to develop your Cocoa application. You've laid out your user interface, you've connected your code to your user interface, either for Carbon and Cocoa, and now you want to load this user interface inside your application.

So here again, there is a difference between Cocoa and Carbon. In Carbon, there are no objects. So you have to explicitly load your user interface and get object outside of the nib. In Cocoa, it is more or less automatic. There is also a nib which we call the main nib, which is automatically loaded when your application is launched.

And also a nib can be loaded on demand. So let me go first explain about Carbon. In Carbon there is one header, the ibcarbon-runtime.h, which has six functions, a very small API. And the six API allows you to load a Nib file and get anything outside of this Nib file-- windows, menus, et cetera.

Those APIs are available on Mac OS X, apart of the Carbon framework. So if you're using, you're linking against Carbon, you're already getting those APIs ready to use. And on Mac OS X, Mac OS 9 and 8, I should have said 8 also, we are part of Carbon Nib since 1.1. So you can use Nib file and you can use the same API, the same code to load your Nib file on 8 or 9.

So here I have a typical, very small application, Carbon application, that by the way will run perfectly well. And what I'm doing here is that I'm first getting a reference to a Nib file. I call create Nib reference, passing the name of the Nib file, and I get back a Nib reference. I can then ask for the menu bar inside this Nib file, and it happens I call my menu bar in my Nib file. So I can say, set the main menu bar using the menu bar that's inside this Nib.

I can also then create a window from the Nib file, same thing, passing a Nib reference, passing the name of the window you want to extract, and you get a window reference. I immediately dispose the Nib reference. You should not keep those Nib reference around because we are loading some XML file, etc. You want to get rid of them as soon as you are done.

The window was created invisible, so now you just say show window and the window pops on the screen. And you can go and run, go and call run application event loop, and you're done. And this application will run fine, providing a Nib that has those two objects that will put a menu bar and a window on the screen.

Cocoa. So for Cocoa, there is one special Nib file, which we call the main Nib file. This Nib file is automatically loaded at launch time. When you launch a Cocoa application, the main Nib file is automatically loaded. The name doesn't have to be main. It can be anything you want. You can go in the Project Builder, Application Settings tab, and you can change the name of this Nib the way you want.

Usually, this Nib file should contain the menu bar, at least the menu bar, because this is the UI that you want to come up immediately when you launch your application. So a good place for your menu bar is inside the main Nib. The file owner of this main Nib will be the application object, because the application is loading this Nib file.

So this is a good place, for example, if you want to connect some menu item to the application-- for example, you have implemented some code in your application, and you want to connect menu item to your application-- you can define those target actions on your application. You can also do some action on your file owner, which is the application, and connect your menu item to the file owner, because the file owner is the application.

Other Nib files should be loaded lazily. You can explicitly load a Nib file using NSBundle, loadNIPName, owner. We have also some other API to load Nib file, but this is the one that's the most used. You can also use NSWindowController. It's a class that you should try to use whenever possible.

If you use a window controller, the window controller is created outside of the Nib, and the file owner of this Nib will be the window controller. We've just added a new sample in the CD you got at the conference called Simple MultiWindow. It's a Cocoa sample that shows you how to create an application with multiple Nib and how to use window controller.

So now I would like to go and cover some tips and tricks, some things that you need to know about Interface Builder that will make your life much easier. And ours too. So let's go through some tips and tricks here. First, an important one. Do not put all your UI in one big, giant nib.

This is not the way a nib file should be used. This is very important, especially for Carbon developer, which are used to a resource fork with a bunch of DLOG, DITL, all the applications in one big, huge resource fork. Nib files are not resource files and should not be used like you used to use resource files. You should break up your UI in as many nibs as possible. Because when you load a nib file, in Cocoa, when you load a nib file, all the objects in the nib file will be loaded automatically. All windows will be instantiated. Everything will be loaded at once.

On the Carbon side, there are no objects, but still we'll be loading a lot of extra XML just for you to get one window. So if you break up your UI in multiple nibs, your nib will load faster. And also, it will facilitate reuse. If you have this nice about box you want to reuse in another application, it's much easier to just copy your nib file and your source code. And bring it to the other application instead of trying to extract your window, your controller, et cetera. So break up your UI in multiple nibs.

As an example, here I have a Carbon application, a bad Carbon application, which has four windows and a menu bar. This application has a menu bar, a main window, an about box, a connection panel, and some preference panel. This is bad. This is not the way you should do it. What you should do is have, in this case, four nibs.

One with your main window and your main menu because in this case this is a single window type of application with one window and a menu bar. So you put your window and your menu bar into your main nib. You load this UI when you launch your application.

Then you need to have a nib with your about box, a nib with your connection panel, and a nib with your preferences. If the user never uses your preference or your about box, there is no need to load this nib file. Top level objects. You get something to drink.

Couple of objects. This is specific for Cocoa. In a Nib file, you have this document window with a bunch of icons. We talked about the first, the file owner and the first responder, which are not real objects, they are just proxy objects for objects that are outside of the Nib file. But here, I highlighted three objects. There is a menu bar, a window, and a controller object. This is for Cocoa. Carbon, I don't have to worry about top level objects too much.

So, typically this is what you used to have in a Nib file traditionally. You used to have a controller, windows and menu.

[Transcript missing]

So, new type of top level objects and I will talk more about the view in a few minutes. So I'm talking about those top level objects because of ref counting. You know that Cocoa used reference counting, so an object is created, if you call alloc init, your ref count is one.

Creating an object in a Nib file is exactly like calling alloc init. If you instantiate a window inside a Nib file, it's like in your code calling NSWindow, alloc init, whatever, plus extra parameters. So this is really creating an object, and you get an object with a ref count of one, which means that if you don't do anything, you have a leak because you're loading a Nib file and suddenly this Nib file is not needed anymore. Those objects are still there.

Someone asked to release those objects. So the role of the--who should release those objects is usually the file's owner. The way to do that, for example, would be to have an outlet inside your file owner that will connect to a window or connect to another object inside your Nib. And when the controller decides, "Oh, I'm going to do this," the file owner decides that this Nib is not needed, it will release those objects. This is very, very important.

There's one exception. NSWindow has this little flag called Release on Close, which means when I'm close, get rid of myself. So it just releases itself. So an NSWindow, you don't have to worry about that because if you set this flag, Release on Close, it will go away automatically. For all other objects, you have to be very careful that someone has to own this object, someone has to have an outlet on this object, and knows how to release it when you're done with the Nib file.

So, windowless view. This is new in Interface Builder. It's a very, very useful feature. It allows you to create a view without an enclosing window. To do that, you simply drag a custom view. We have a custom object on the palette. You just simply drag a custom view inside your document window and you instantiate an NSView. You can then change the class of this NSView. It can be MyView, whatever.

This eliminates the need to create a window. A couple of years ago, what you had to do is create a window at runtime, have an outlet on this window, Get a pointer to the content view and get rid of the window. So you have to write a little bit of code to just get a view by itself without a window. You don't have to do that anymore now. You can just create a view. You can put control inside this view and you can just instantiate this view by itself.

Which makes me think also that there's something that's important, a new feature in Interface Builder for people who use Cocoa for a while. You can also now embed control in a custom view. It's something you could not do before. You can only embed things into a group box or something like that. You can use now a custom view as a container.

So we use this windowless view as the content view of an NS drawer. This is one of the usage we have of windowless view. But you can use windowless view for anything you want. Be very careful with the ref counting again. This view is going to be created. If you have an outlet with this view and you put this view inside another view, now the ref count is two. This content view goes away. The ref count of your view is still one. So it's not going away. You have to be careful of the reference counting.

We have the windowless view in Carbon and we bring that to Cocoa. No, sorry, we have that in Cocoa and bring that in Carbon where we'll be able to create a user pane without a view and be able to manipulate this user pane and put it wherever you want. So that's a feature for Carbon.

Post-Nib loading initialization. I think that's one of the questions that come up more often on different mailing lists. I have this object in a nib and I override init with frame and my init with frame is not called. Why? Because the rule here is do not rely, don't rely on init, init twist frame or init twist coder to do any post loading, post nib loading initialization.

The way to do that is to implement AwakeFromNib. Any object can implement AwakeFromNib and when we load a nib file, when we instantiate all those objects, the last thing we do is that we ask every object, do you implement AwakeFromNib? If the object says yes, we call AwakeFromNib. This is the last thing we do.

So at this point, all objects have been instantiated. Everything in your nib has been instantiated. All the outlet target actions have been set. So all the objects are ready to go. So never try to override init, init twist frame or init twist coder to do any post nib loading initialization. Implement AwakeFromNib. This is the right place to do that. Nib tool.

NibTool is a handy little tool. It's a command line tool that we have that allows you to manipulate the content of a Nib file without using Interface Builder. It's a command line tool. It works for both Cocoa and Carbon, so you can both accept Cocoa and Carbon nibs. And there are a lot of options. We just added a ManPage to NibTool, so you have all the options using ManPage.

It's used by FileMerge to diff to nibs. Cocoa nibs are a binary, so FileMerge cannot show you the difference between what changes on Nib files. So what FileMerge does is that it invokes NibTool on those two nibs, asking NibTool to convert those two nibs into a textual representation. And then you can do a diff of those two Nib files. We've added-- A feature recently to allow localization of a Nib file using Nib tool.

Let's say that you have an English nib and you want to translate it into a French nib. One way to do that would be to open your English nib into Interface Builder and have someone figuring out where are all the strings, trying to find where the strings are so you can localize those strings. There is a new way to do that now.

What you can do is you can use Nib tool and ask Nib tool to extract all the strings from this Nib file. So the output of Nib tool will be a text file that looks like hello equal hello, close equal close, open equal open. So it's a way to extract all the strings from this Nib tool. You can then send this text file to a localizer and ask him to translate the right side of the string, of the equal sign.

And when you get back your text file localized, you can send it back to Nib tool using the original English Nib file and create a French Nib. IB will know where to put back those strings in the right place. So you may have to go back and still open the Nib file and readjust some button, would be too short or too long, but you can make the localization a lot more automatic. And in fact, this is one way we're doing that at Apple to localize Nib files.

We have a process which is a bit more complex than this one that use Nib tool to localize automatically all the Nib file without any intervention of engineers. So there is a session Thursday on how to localize your application. And if you're interested to look at that, go to this session.

[Transcript missing]

In the box that came with Mac OS X, there was a developer CD. And on this CD there was Interface Builder version 2.0. I think IB was version 1.0 for 15 years, so we decided it was a good time to go to 2.0. So this is version 2.0.

We know our shipping version 2.0.1 at the conference. And it's many bug fixing. We have some bugs fixed for web objects. There's many bug fixes. There are no new features there. But we've added two new examples. We have an example called Busy Palette and Simple Multi Window. These are both Cocoa examples.

The Busy Palette is--there's been a lot of demand recently for people wanting to write palettes. And we haven't talked about that today, but this sample is a complete palette example that shows you how to support undo in your object when you're writing a palette, to show you how to write inspectors, show you how to write multiple modes for the inspector, for example. When you drag a formatter on the text field, you get another inspector. So how to add inspector to the inspector window. That's what says the info window.

But this is a full complete palette sample that I'm sure a lot of you will find very useful. There's also a Simple Multi Window example, which I took before, showing you how to write an application with multiple windows using an S Window Controller. Interface Builder will be released using the quarterly developer update. So as we have new features and new bug fixes, you will see a new version of IB coming out.

I just want to talk briefly about what's coming up, what new features we have scheduled for Interface Builder. First we want to continue to concentrate on the stability of the product. We want to make it faster, stable, easier to use. As far as easier to use, and Scott was talking about that, we got a lot of feedback about how you edit those containers. You have to double click all these things.

So we are changing that. You'll find a much better, more intuitive way to edit containers. You won't have to double click all these things. It will be much more natural. We're also changing the UI to define outlet and action. I think a better UI to define those outlet and actions.

For people who are familiar with Interface Builder, on Cocoa there is a class tab and right now it shows an outline view. We are also giving you the choice to use a browser view, which is much easier to navigate, and also give you a search feature so you can type NSV and it's going to go to NSV automatically. We are also adding flagging of unconnected outlet and actions, the target actions.

This is very useful because sometimes if you have a very complex user interface and you have a lot of menus, items, a lot of questions, you may miss a connection and sometimes you don't understand why your application doesn't work. So now we will be showing you what is not connected in Interface Builder. For example, it's very important that if you have an S-Window controller that the window outlet be correctly connected to the window. So if you don't do that, your application may not work. So we will be flagging those unconnected outlets and actions.

We want to continue to improve PB and IB integration. We want to take advantage of the indexer. We want to make sure that we have a good indexer in PB. So this is something important we have to be able to use. And also we are continuing to closely track Cocoa and Carbon frameworks.

Cocoa and Carbon are adding new features, new UI elements, and we want to have IB to always be on top of that, always be ready for you to use those new UIs in both Cocoa and Carbon. So we are working, in fact we are part of the Cocoa and Carbon teams, and we are very closely what changes are made to those two frameworks to renew the latest user interface. And we have a lot more EIDs and features coming up pretty soon. I'd like to bring back Godfrey on stage and I went very, very fast today. So we have time for . Thank you very much, Henri.

Pretty amazing stuff. The use of Interface Builder for Carbon and Cocoa really ensures much, much better Aqua user interfaces. It's an essential part of the Cocoa development and really helps you use your Carbon events to the greatest effect. On the screen right now, information resources. Again, our information pages for all Mac OS X tools.

The project, somebody copy and pasted the wrong, that should be the Interface Builder web page there. And below that, the master mailing list page for all the different mailing lists that we support at Apple. There's Project Builder users, there's Cocoa dev, there's also Carbon dev and the web objects lists, all of which will be using Interface Builder.

A roadmap for more sessions. Carbon event manager, right here after this session. Tomorrow, using Cocoa. Actually, Thursday, using Cocoa and the advanced Cocoa topics. And the Mac OS X application localization. And now, if I can have the house lights up, people can start coming up to the microphones to ask their questions. This is my contact information if you have strategic questions regarding tools of any sort. I am your technology manager to deal with those. And also for feedback to the Mac OS X tools groups, we have a mailing list direct, a mailing address specifically for that purpose.