08: A Program With a GUI


Introduction

Having increased our knowledge of Objective-C, we are ready to discuss how to create a program with a Graphical User Interface (GUI). I have to confess something here. Objective-C is actually an extension of a programming language called C. Most of what we have discussed so far is just plain C. So how does Objective-C differ from plain C? It is in the "Objective" part. Objective-C deals with abstract notions known as objects.

Up until now we have mainly dealt with numbers. As you learned, Objective-C natively supports the concept of numbers. That is, it let you create numbers in memory and manipulate them using math operators and mathematical functions. This is great when your application deal with numbers (e.g. a calculator). But what if your application is, say, a music jukebox that deals with things like songs, playlists, artists etc.? Or what if your application is an air traffic control system that deals with planes, flights, airports etc.? Wouldn't it be nice to be able to manipulate such things with Objective-C as easily as you manipulate numbers?

This is where objects kick in. With Objective-C, you can define the kind of objects you are interested to deal with, and then write applications that manipulate them.

Objects in action

As an example, let's take a look at how windows are handled within a program written in Objective-C, such as Safari. Take a look at an open Safari window of your Mac. At the top left, there are three buttons. The red one is the close button. So what happens if you close a window by clicking that red button? A message is sent to the window. In response to this message, the window executes some code in order to close itself.

09 Object Action

A close message is sent to the window

The window is an object. You can drag it around. The three buttons are objects. You can click them. These objects have a visual representation on screen, but this is not true of all objects. For instance, the object that represents a connection between Safari and a given web site does not have a visual representation on screen.

10 Object Buttons

An object (e.g. the window) can contain other objects (e.g. the buttons)

Classes

You can have as many Safari windows as you want. Do you think that Apple's programmers:

  • a. programmed each of those windows in advance, using their massive brainpower to anticipate how many windows you might want to have, or
  • b. made a kind of template and let Safari create the window objects from it on the fly?

Of course, the answer is b. They created some code, called a class, which defines what a window is and how it should look and behave. When you create a new window, it is actually this class that creates the window for you. This class represents the concept of a window, and any particular window is actually an instance of that concept (in the same way that 76 is an instance of the concept of a number).

Instance Variables

The window you created is present at a certain location on the screen of your Mac. If you minimize the window to the Dock, and make it reappear, it will take exactly the same position on the screen that it had before. How does this work? The class defines variables suitable for remembering the position of the window on the screen. The instance of the class, i.e. the object, contains the actual values for these variables. So, each window object contains the values of certain variables, and different window objects will in general contain different values for those variables.

Methods

The class not only created the window object, but also gave it access to a series of actions it can perform. One of those actions is close. When you click the "close" button of a window, the button sends a close message to that window object. The actions that can be performed by an object are called methods. As you will see, they resemble functions very closely, so you will not have much trouble learning to use them if you have followed us so far.

Objects in memory

When the class creates a window object for you, it reserves memory (RAM) to store the position of the window and some other information. However, it does not make a copy of the code to close the window. That would be a waste of computer memory because this code is the same for every window. The code to close a window needs to be present only once, but every window object has access to that code belonging to the window class.

As before, the code you are about to see in this chapter contains some lines for reserving memory and releasing it back to the system. As indicated earlier, we will not discuss this advanced subject until much later. Sorry.

Exercise

Our Application

We are going to create an application with two buttons and a text field. If you press one button, a value is entered into the text field. If you press the other button, another value is put into the text field. Think of it as a two-button calculator that can't do calculations. Of course, once you learn more you can figure out how to create a calculator for real, but I like small steps.

11 Our App

A sketch of the application we want to create

If one of the buttons of our app is pressed, it will send a message. This message contains the name of a method to be executed. This message is sent to, well, to what? In case of the window, the close message was sent to that window object, which was an instance of the window class. What we need now is an object that is capable of receiving a message from each of the two buttons, and can tell the text field object to display a value.

Our first class

So, we first have to create our own class, and then create an instance of it. That object will be the receiver of the message from the buttons (Please refer to the sketch below). Like a window object, our instance is an object, but in contrast to a window object, we can't see our instance on the screen when we run the program. It is just something in the memory of the Mac.

When our instance receives a message sent by one of the (two) buttons, the appropriate method is executed. The code of that method is stored in the class (not in the instance itself). Upon execution, this method will reset the text in the text field object.

How does the method in our own class know how to reset the text in a text field? Actually, it doesn't. But the text field itself knows how to reset its own text. So we send a message to the text field object, asking it to do just that. What kind of message should that be? Of course, we need to specify the name of the recipient (i.e. the text field object in our window). We also need to say, in the message, what we want the recipient to do. We specify that by using the name of the method that the text field will have to execute upon receipt of the message. (Of course, we need to know what methods text fields can execute, and what they are called.) We also need to tell the text field object what value to display (depending on the button clicked). So, the message sending expression not only contains the name of the object and the method name, but also an argument (value) to be used by the method of the text field object.

12 Our Class

A sketch of message exchanges between the objects in our application

Here is the general format of how to send messages in Objective-C, both without [1.1] and with [1.2] an argument:

//[1]
[receiver message];
[receiver messageWithArgument:theArgument];

As you can see in each of these statements, the whole shebang is placed between square brackets and the eternal semi-colon is present as the finishing touch. Between the brackets, the receiving object is mentioned first, followed by the name of one of its methods. If the method being called requires one or more values, they must be provided as well [1.2].

Creating the project

Let's see how this works for real. Start up Xcode to create a new project. Select Cocoa Application under the Application heading. Give your project a name, like "My First App" (by convention, the name of your GUI application should start with a capital). In the Groups & Files frame of the Xcode window that appears, open the Resources folder. Double-click on MainMenu.xib.

13 Xcode Nib

Double click on the MainMenu.xib file in Xcode

Prior to Xcode 3, xib files were known instead as nib files, for NeXT Interface Builder. If you are using an older version of Xcode, you may see a MainMenu.nib file instead. This detail is not important - to all intents and purposes, they are the same thing.

Creating the GUI

Another program, Interface Builder, will start-up. As a lot of windows appear, you may want to choose Hide Others from the File menu. You will see three windows. The one named "Window" is the window that the users of your application will see. It is a bit big, so you may want to resize it. To the right of the window "Window", there is a window named "Library". It is a kind of repository for all kinds of objects you can have in your GUI and is known as the "Library palette". Select the "Objects" item in the list at the top of this window and drag two Buttons, one at a time, onto the GUI window "Window". Similarly drag one text Label having the text "Label" onto the GUI window.

14 Create Gui

Dragging GUI objects from the palettes window to your application's window.

Behind the scenes, the action of dragging a button from the palettes window to your application's window creates a new button object and puts it in your window. The same goes on for the text field and any other objects you might drag to your window from the palettes window.

Note that if you hold your cursor over an icon in the palettes window, a name will be displayed, such as NSButton or NSTextView. These are the names of classes provided by Apple. Later in this chapter we will see how we can find the methods of these classes, which we need to perform the necessary actions in our program.

Don't forget to save your nib regularly so that Xcode and IB are able to stay in sync.

Arrange the objects you dragged onto the window "Window" nicely. Resize them as you see fit. Change the text of the button objects by double-clicking them, one at a time. I invite you to explore the palettes window after we have finished this project to get a grip on how to add other objects to your window.

Exploring Interface Builder

To change the properties of an object, select it and press Cmd-Shift-I. Explore this as well. For example, select the window "Window" (you can see it gets selected in the xib window) and press Cmd-Shift-I. If the title bar the top reads Window Attributes, you can set a tick for Textured, and this gives your window a metal look. You will find that you can customize the look of your application to a large extent without writing a single line of code!

15 Explore Ib

Our window in Interface Builder, along with its inspector

Working with classes

Switch back to Xcode now. In your project window, if you open the Classes folder in the Groups & Files pane, you will see that there are two items with names starting with "My_First_Application_AppDelegate". These two files are the basic class that Xcode has created automatically for you. The file that ends in ".h" is the Header or Interface file for the class. The one that ends in ".m" is the Main or Implementation file for the class.

16 App Delegate

The Application Delegate class that is included with every new Cocoa application.

Every Cocoa application needs at least one class to do anything useful. By convention, the basic class is known as the Delegate, because it can implement a set of Delegate methods to customise the behaviour of Cocoa's NSApplication class. More about this later.

Class background

Let's look a bit deeper into how classes work.

To save a lot of programming effort, it would be nice if you could build on what others have already built, instead of writing everything from scratch. If you, for example, wanted to create a window with special properties (capabilities), you would need to add just the code for these properties. You wouldn't need to write code for all other behavior, such as minimizing or closing a window. By building on what other programmers have done, you would inherit all these kinds of behavior for free. And this is what makes Objective-C so different from plain C.

How is this done? Well, there is a window class (NSWindow), and you could write a class that inherits from that class. Suppose you add some behavior to your own window class. What happens if your special window receives a "close" message? You didn't write any code for that, and didn't copy such code into your class either. Simple, if the class of the special window doesn't contain the code for a particular method, the message is transferred automatically to the class from which the special window class inherits (its "superclass"). And if necessary, this goes on until the method is found (or it reaches the top of the hierarchy of inheritance.)

If the method cannot be found, you sent a message that can't be handled. It is like requesting a garage to change the tires of your sleigh. Even the boss of the garage can't help you. In such cases Objective-C will signal an error.

Custom classes

What if you want to implement your own behavior for a method already inherited from your superclass? That is easy, you can override particular methods. For example, you could write code that, on clicking the close button, would move the window out of view before actually closing it. Your special window class would use the same method name for closing a window as the one defined by Apple. So, when your special window receives a close message, the method executed is yours, and not Apple's. So, now the window would move out of sight, before being closed for real.

Hey, closing a window for real was already programmed by Apple. From inside our own close method, we can still invoke the close method implemented by our superclass, although it requires a slightly different call to make sure our own close method is not called recursively.

//[2]
- (void) close:(id)sender {
    // Code to move the window out of sight here.
    [super close]; // Send the close message to the superclass.
}

One Class to rule them all

King of the hill, among classes, is the class named NSObject. Nearly all the classes you will ever create or use will be subclasses of NSObject, directly or indirectly. For example the NSWindow class is a subclass of the NSResponder class, which is itself a subclass of NSObject. The NSObject class defines the methods common to all objects (e.g. generating a textual description of the object, asking the object whether it is able to understand a given message etc.)

Before I bore you with too much theory, let's see how to create a class.

Creating a class

Go to the your Xcode project and select New File from File menu. Choose an Objective-C class from the list, make it an NSObject subclass, then click Next. I named mine "MFAExampleClass". Click Finish.

16 Subclass MFAExampleClass

Creating the MFAExampleClass class

Once you have clicked Finish, you should see two new files in your Groups & Files pane.

The first three capitals of MFAExampleClass stand for My First Application. You can invent class names as you like. By convention, all class names begin with one or more capital letters, and they may not contain any spaces. Once you start writing your own applications, we recommend that you choose a two or three letter prefix that you'll use for all your classes in order to avoid confusion with existing class names. However, don't use NS, as this may confuse you later on. NS is reserved for Apple's classes. It stands for NeXTStep, NeXTStep being the operating system Mac OS X was based on when Apple bought NeXT, Inc.

The CocoaDev wiki contains a list of other prefixes to avoid. You should check it when choosing your own prefix: http://www.cocoadev.com/index.pl?ChooseYourOwnPrefix

When creating a new class you should give it a name that conveys useful information about that class. For instance, we've already seen that in Cocoa the class used to represent windows is named NSWindow. Another example is the class that is used to represent colors, which is named NSColor. In our case, the MFAExampleClass class we are creating is just here to illustrate the way objects communicate together in an application. This is why we gave it a generic name with no special meaning.

Creating an instance in Interface Builder

Back in Interface Builder, go to the Library palette and choose Objects & Controllers from the top menu. Then drag an Object (blue cube) from the palette to the MainMenu.xib class.

18 Instantiate

Instantiating a new object

Next, select the Identity button in the Inspector palette (Cmd-6), then choose MFAExampleClass from the Class pop-up menu. We have now instantiated our MFAExampleClass class in Xcode into an object in our xib file. This will allow our code and our interface to communicate.

19 Identity

Setting the identity of our object instance

Creating connections

Our next step is to create connections between the buttons (from which messages are sent) to our MFAExampleClass object. In addition, we are going to create a connection back from the MFAExampleClass object to the text field, because a message will be sent to the text field object. An object has no way of sending a message to another object if it doesn't have a reference to the other object. By making a connection between a button and our MFAExampleClass object, we are providing that button with a reference to our MFAExampleClass object. Using this reference, the button will be able to send messages to our MFAExampleClass object. Likewise, establishing a connection from our object to the text field will allow the former to message the latter.

Let us again go through what the application has to do. Each of the buttons can send, when clicked, a message corresponding to a particular action. This message contains the name of the method of the class MFAExampleClass that has to be executed. The message is sent to the instance of the MFAExampleClass class we've just created, the MFAExampleClass object. (Remember: object instances themselves don't contain the code to perform the action, but the classes do.) So, this message sent to the MFAExampleClass object triggers a method of the class MFAExampleClass to do something: in this case, sending a message to the text field object. Like every message, this one consists of the name of a method (which the text field object will have to execute). In this case, the method of the text field object has the task of displaying a value, and that value has to be sent as part of the message (called an "argument", remember?), along with the name of the method to invoke on the text field.

Our class needs two actions (methods), which will be called by the (two) button objects. Our class needs one outlet, a variable for remembering which object (i.e., the text field object) is to be sent a message.

Open the Library palette, and select the Classes tab at the top of the window. This will show you all the Classes in the Cocoa Frameworks and their attributes. At the bottom of the window is a search field. Begin typing MFAExampleClass in this field and you will see the MFAExampleClass displayed in the first pane.

18 Add Actions

MFAExampleClass in the class library

In the palette, in the Action section, click the Add (+) button to add an action (i.e., an action method) to the MFAExampleClass class. Replace the default name provided by Interface Builder by a more meaningful name (for example, you can enter "setTo5:" because we will program this method to display the number 5 in the text field). Add another method, and give it a name (for example "reset:", because we will program it to display the number 0 in the text field). Note that our method names both end with a colon (":"). More about this later.

18 Add Actions

Adding action methods to the MFAExampleClass

Now select the Outlet tab, add an outlet and give it a name (for example "textField").

18 Add Actions

Adding outlets to the MFAExampleClass

Before establishing connections between objects, we are going to give meaningful names to our two buttons. Since the first one is going to ask our Example Class instance to display the number 5 in the text field, we name it "Set to 5" (we already learned how to change the name of a button: double click on its name on-screen, and then enter the new name). Likewise, we name the second one "Reset". Note that this step of giving this button a particular name is not required for our program to work correctly. It is just that we want our user interface to be as descriptive as possible to the end-user.

Now we are ready to create the actual connections between

  1. the button "Reset" and the MFAExampleClass instance
  2. the button "Set to 5" and the MFAExampleClass instance
  3. the MFAExampleClass instance and the text field.

To create the connections, press the Control key on you keyboard and use the mouse to drag from the "Set to 5"" button to the MFAExampleClass instance in the MainMenu.xib window (don't do it the other way around!). A line representing the connection will appear on screen, and a menu will pop up on the object instance icon. Choose "setTo5:" from the list.

20 Connect

Establishing the connection

Now the button holds a reference to our MFAExampleClass object, and will send it the setTo5: message whenever it is pressed.

You can now connect the "Reset" button to the MFAExampleClass object by applying the same process.

To create the connection between the MFAExampleClass object and the text field, start from the MFAExampleClass object and control-drag to the text field object. Click "textField" in the menu to assign the connection.

What was this all about? Well, as you will see in a minute, you have just in effect created some code without writing a single line.

Generate Code

First, make sure MFAExampleClass is selected in the MainMenu.xib window. Go to the File menu in Interface Builder and choose Write Class Files. Interface Builder then asks you where you want your generated file to be put on disk. Navigate to the project folder of our application and overwrite the MFAExampleClass class that exists there. Make sure you set the Language pop up to Objective-C and check "Create '.h file". Replace the existing class files when prompted.

23 Code

Now, if you switch back to Xcode, you'll see the generated files in your project window, inside the Classes group. If they appear in the Resources group, or a different group, simply select and then drag them to the Classes group. Click on the Editor toolbar button, then choose MFAExampleClass.h.

23 Code

The generated files appear in our Xcode project

Let's go back for a moment to Chapter 3, where we discussed functions. Do you remember the function header [11.1]? It was a kind of warning for the compiler to tell it what it could expect. One of the two files we have just created is named MFAExampleClass.h, and it is a header file: it contains info about our class. For example, you'll recognize that there is a line [3.5] containing NSObject, which line means that our class inherits from the NSObject class.

//[3]
/* MFAExampleClass */
#import <cocoa/cocoa.h>  // [3.2]
@interface MFAExampleClass : NSObject
{
    IBOutlet id textField;	// [3.7]
}
- (IBAction)reset:(id)sender;
- (IBAction)setTo5:(id)sender;
@end

You will see that there is one outlet [3.7] to the text field object. id indicates object. "IB" stands for Interface Builder, the program you used to create this code.

IBAction [3.9, 3.10] is equivalent to void. Nothing is returned to the object that sends the message: the buttons in our program do not get a reply from the MFAExampleClass object in response to their message.

You can also see there are two Interface Builder Actions. These are two methods of our class. Methods are quite like functions, which we already know, but there are differences. More on that later.

Earlier we have seen #import <Foundation/Foundation.h> instead of line [3.2], The former is for non-GUI apps, the latter for GUI-apps.

Now let's check out the second file, MFAExampleClass.m. Again we get a lot of code for free.

//[4]
#import "MFAExampleClass.h"
@implementation MFAExampleClass
- (IBAction)reset:(id)sender	// [4.5]
{
}
- (IBAction)setTo5:(id)sender
{
}
@end

First of all, the MFAExampleClass.h header file is imported, so the compiler knows what to expect. Two methods can be recognized: reset: and setTo5:. These are the methods of our class. They are similar to functions in that you need to put your code between the curly braces. In our application, when a button is pressed, it sends a message to your MFAExampleClass object, requesting the execution of one of the methods. We do not have to write any code for that. Making the connections between the buttons and the MFAExampleClass object in Interface Builder is all what is required. However, we do have to implement the two methods, i.e. we need to write the code that performs their function. In this case, these methods do nothing but send a message each from our MFAExampleClass object to the textField object, so we provide the statements [5.7, 5.12].

//[5]
#import "MFAExampleClass.h"
@implementation MFAExampleClass
- (IBAction)reset:(id)sender
{
    [textField setIntValue:0];	// [5.7]
}
- (IBAction)setTo5:(id)sender
{
    [textField setIntValue:5];	// [5.12]
}
@end

As you can see, we send a message to the object referenced by the textField outlet. Since we connected this outlet to the actual text field, using Interface Builder, our message will be sent to the correct object. The message is the name of a method, setIntValue:, together with an integer value. The setIntValue: method is capable of displaying an integer value in a text field object. In the next chapter we will tell you how we found out about this method.

Ready to rock

You are now ready to compile your application and launch it. As usual press the Build and Go button in the Xcode toolbar. It will take a few second for Xcode to build the application and to launch it. Eventually, the application will appear on screen and you'll be able to test it.

23 Run

Our application running

In short, you have just created a (very basic) application, for which you had to write just two lines of code yourself!

window attributes

i'm new to programming and up to now i found this tutorial very useful. i use xcode4 and i encountered my first problem: when i select an object and press Cmd-Shift-I, the program gets built, but i don't get the "window attributes" window. can anyone tell me how i can get it?

Submitted by Alice (not verified) on Mon, 04/11/2011 - 17:32.
Needs some definite updating

So Xcode 4 changes a lot about this. I got around it by manually entering in the code into the MAFoo class and then doing the control-dragging, but I am not sure if that is what you are supposed to do.

Realistically this chapter probably should be split out and expanded on a bit further. The difference between methods and functions isn't quite clear to me nor is what is really going on with the MAFoo class.

Submitted by anon (not verified) on Sat, 03/19/2011 - 18:30.
Thank you so much for

Thank you so much for posting this!

Submitted by Anonymous (not verified) on Sat, 01/22/2011 - 03:01.
Wired Impressions

Being new to mac programming and objective C, it seems to me that, after reading this chapter, it appears the one cannot look at the source code and know what objects (buttons etc) are wired to what methods and outlets.

In this example, looking at MFAExampleClass, you can see that there are two methods and an outlet, but you cannot determine which GUI elements are calling these methods.... unless you have IB running and right click on the various GUI elements.

Does this mean that one person cannot debug another person's code without IB running?

Submitted by Dave (not verified) on Sat, 07/24/2010 - 04:19.
Re: Wired Impressions

Hi Dave,

You are correct, and this is certainly a weakness in the approach that Xcode takes. It is difficult to see how it could be solved in the context of having a tool such as Interface Builder working along side coding in an editor like Xcode.

Still Xcode 4 may make things better. We'll see soon.

Cheers,

Alex

Submitted by alex on Wed, 07/28/2010 - 12:34.
Sorry, I cannot find how to

Sorry, I cannot find how to do this small thing at all in Xcode 4:

"Open the Library palette, and select the Classes tab at the top of the window."

I've tried for ages to create two new actions in IB for the custom object but cannot find how to do it in Xcode 4.

Do you know how to do this?

Thanks a lot for these tutorials, they are great.

Submitted by Andy (not verified) on Thu, 03/24/2011 - 18:17.
iPhone compatible?

Great "book", thank you!
But doesn't work for iPhone - the app stops working in the simulator after clicking a button ;(
But well, still very helpful

Submitted by Postingguy (not verified) on Tue, 04/27/2010 - 17:47.
No buttons??

I've followed everything up to this point and so far as I can tell, even after double checking I've done everything correctly. My written code exactly matches your examples but for some reason when I build and go, the window opens with no buttons or text field. Any idea why this is happening?

Submitted by Jonathan (not verified) on Thu, 04/22/2010 - 19:15.
I hit the same problem.

I hit the same problem. Although you pushed your classes, you also have to save the XIB file. Do that by going to File--> Save and that should solve your problem.

Submitted by Hugh Ferguson (not verified) on Wed, 12/01/2010 - 22:38.
Did you save in Interface Builder

I had the same issue, but realised I didn't save in Interface Builder. After saving everything was fine :)

Submitted by Thomas (not verified) on Thu, 11/04/2010 - 23:24.
thank you

I want to say: THANK YOU VERY MUCH for your work!
i spent a lot of time reading several tutorials about Xcode (Objective-C) programing and it looked so difficult.
Than i decide to use QT with C++ but especially for Mac it's obvious XCode is much better.Now after reading your
tutorial i find XCode as super easy and natural.i'm pretty impressed and i wish you all the best!!!
By the way, is there similar tutorial for iPhone programming with Xcode?

Submitted by Anonymous (not verified) on Tue, 04/13/2010 - 13:01.
Lost in directions

Alex,

None of this happened. Cannot follow you from this point. Seems that a few others had similar problems but I could not find any solutions offered to fix it at this point.

Thanks!
Xcode 3.14

Working with classes

Switch back to Xcode now. In your project window, if you open the Classes folder in the Groups & Files pane, you will see that there are two items with names starting with "My_First_Application_AppDelegate". These two files are the basic class that Xcode has created automatically for you. The file that ends in ".h" is the Header or Interface file for the class. The one that ends in ".m" is the Main or Implementation file for the class.

Submitted by Anonymous (not verified) on Sun, 03/28/2010 - 23:00.
Re: Xcode 3.1.4 and Class Files

In Xcode 3.1.4 to create the class files : When you're done building the GUI elements in Interface Builder, select the new object that you created in MainMenu.xib. Go to File > Write Class files. It may ask you to select the project you want to associate it with. Click on your project name - My First App
If your Xcode project was open during this time, you would see the class files under Products instead of classes folder. You can drag it to classes folder if you like.
HTH.

Submitted by Ruchi (not verified) on Fri, 04/23/2010 - 14:46.
delegate class files not present

Hi, I am trying to follow the book. I am stuck though - when I try to create a cocoa application, it does not create the delegate files. It does not create the files My_First_Application_AppDelegate.h and My_First_Application_AppDelegate.m. There are no files in the classes group. Please help me solve this. I'm sure there is a simple, stupid solution. This is a wonderful tutorial, and I am very frustrated that I am stuck so early in it.

Submitted by Jeff (not verified) on Sun, 01/31/2010 - 19:26.
Some errors

Great tutorial so far! Just wanted to point out a few errors on this page:

Working with Classes section: "My_First_Application_AppDelegate" doesn't match the image below. Should be "My_First_AppAppDelegate"

Code example 3: // [3.7] should be // [3.5]; and the text below should be updated accordingly.

Code examples 4 and 5 have similar problems: // [4.5] should be // [4.3]

Submitted by Paul (not verified) on Tue, 01/12/2010 - 21:48.
help

When I opened the class folder there was nothing inside.

Submitted by Anonymous (not verified) on Tue, 12/22/2009 - 00:46.
TextField Background Color

In the Dev Ctr documentation, I read about background color but I seem not able to change a textfield background in code (Yes, I can change it via the property panel). I'm using my experience with Java and Visual Basic, Visual C...etc, where it is very simple to do in code.

This is the line in my code - there are no errors but, I do get a warning that no setBackgroundColor method exits. FYI - I have changed the camel case so, this line is only one of several I tried.

[TextField3 setBackgroundColor:(NSColor *)blueColor];

Also tried:
[TextField3 backgroundColor: (NSColor *)blueColor];

That didn't work either. The more I try Obj-C, the more I like Java!

How to change the color in code?
Thanks and great job on this site!

Submitted by Anonymous (not verified) on Mon, 12/07/2009 - 18:59.
Re: TextField Background Color

Hi,

Each language and API is different, and each one takes time and energy to learn. It is natural to find what you are familiar with to be preferable to that which is new, especially while in the initial phases of learning. Learning can be frustrating. Persistence pays off, though - hang in there.

As for your problem, I can see the reason for your difficulty: (NSColor *)blueColor doesn't do what you think it does. You actually mean to say [NSColor blueColor]. Let's look at the difference between these two statements.

[NSColor blueColor] calls a class method of NSColor and returns a default blue color object. Remember, all messages need to be put inside square brackets. Write the receiver name, then the message to be sent, which must be a method implemented by the receiver.

On the other hand, (NSColor *)blueColor casts the variable blueColor as an NSColor object, but does not return anything. In this context, this doesn't really make any sense. It does nothing to change the actual value stored in the variable, which will be nil unless the variable has already been assigned.

I can guess why you are getting this wrong, though. When you see this method declaration in the documentation, it is written like this:

- (void)setBackgroundColor:(NSColor *)aColor

The (NSColor *)aColor phrase simply means that the value passed after the : must be an NSColor object. To call this method in your code, you do so like this:

[textField setBackgroundColor:aColor];

Now that won't work, unless you have previously assigned the variable aColor to an NSColor object, like this:

NSColor * aColor = [NSColor blueColor];

Because Objective-C accepts infix nested statements, you can do this in one line, like this:

[textField1 setBackgroundColor:[NSColor blueColor]];

That saves you one line of code and a variable assignment, but it is more difficult to understand.

Submitted by alex on Tue, 12/08/2009 - 05:12.
Textfield color - thanks!

Alex - thank you very much. Your explanation is clear. And, you're correct re the info in documentation - which, isn't very clear to new obj-C wanabe coders.

I'll take the model of your explanation and apply it to other info I look at in Dev Ctr doc's.

Again, Thank you!

Submitted by Anonymous (not verified) on Tue, 12/08/2009 - 17:17.
Hi! I'm new to programming

Hi!

I'm new to programming but this book is really helpful! I have a problem right in the beginning of this tutorial. When you say: "Switch back to Xcode now. In your project window, if you open the Classes folder in the Groups & Files pane, you will see that there are two items with names starting with "My_First_Application_AppDelegate".".

I tried this but it doesnt semm that xcode and interface builder are connected and xcode did not generate any code?

Do you know why this might happen?

Thank you,

Submitted by Anonymous (not verified) on Tue, 11/24/2009 - 14:57.
Add two number and display

Well, I can press a button (called calculate) and add two int numbers if they are constants. But, if I try to get input from textfields and add them, I get zero for the answer.

I tried setting the textfields as outlets - didn't help. Here's the .m code snippet:

int xIn1, xIn2; // declare variables

- (IBAction)calculate:(id)sender {

xIn1 = [TextField1 intValue]; // if = constant, it works
xIn2 = [TextField2 intValue];

[resultY setIntValue: (xIn1 + xIn2)];
}

Any help is appreciated - thanks!
@end

Submitted by Anonymous (not verified) on Tue, 12/01/2009 - 01:04.
Add two number and display

Well it's hard to tell from your question, but I'd guess that you haven't connected your IBOutlets correctly in Interface Builder.

Cheers,

Alex

Submitted by alex on Thu, 12/03/2009 - 08:27.
THis book is great!

I've been toying with the idea of programming. I majored in information systems management in college. I'm not great with mathematics and I'd have never made it through a Computer Science program.

But I went through archaic and purely academic procedural programming courses and got nowhere - and had professors that bluntly told me I shouldn't even be in their class.

For kicks I have gone through a couple of chapters of this book and I actually get it! For the first time I really understand the object oriented idea and am learning things that they never taught in school.

I went through this chapter and I actually put it together and the program compiled and ran. It's left me wondering - what else can I do with this thing? I picked this chapter to look at first just because most of what i've messed with recently has been the Microsoft Visual Studio applications. I look forward to learning the stuff in the rest of the book and for the first time I feel like programming is something I can really do.

Cheers to the authors!

Submitted by Anonymous (not verified) on Sun, 11/01/2009 - 22:41.
Updated for Xcode 3.2

Hi guys, just to let you know I have finally updated chapter 8 to reflect recent changes in Xcode 3.2, specifically the location of the controls for Actions and Outlets, which have changed quite a bit.

Cheers,

Alex

Submitted by alex on Sun, 10/18/2009 - 09:55.
Hi guys, i made my way

Hi guys,

i made my way through the tutorial since this capture. If it comes to add an action to the object i stuck. I am using Xcode 3.2 and there is no "add action" field or outlet field. Maybe something changed in Xcode 3.2? Instead of "add action" i got "user definded runtime applications" where i can add Key Path, Type and value. It would be nice if someone could give me a hint ;-)

Submitted by fanity (not verified) on Sun, 09/13/2009 - 18:18.
Applying Actions to Classes

Yo.

Just found out how to apply actions to classes in XCode 3.2
Actually, i do like this method, and it seems a bit more logical to me, but you can draw your own conclutions.

Go to the library, and notice that there are three tabs at the top.

Click on the classes tab, and scrole down to your class.

Next, go to the bottom of the library window, and notice that their are four tabs.

One is actions, and one is Outlet.

Inside these tabs, you should find what was in the inspector in XCode 3.0, stated above in the tutorial.

Just had a play around, and found the tabs.
Admitedly they were a bit hard to find, but you should be able to find them now.

Hope this helps.

Submitted by Richard Hyman (not verified) on Sun, 10/04/2009 - 15:26.
Applying Actions to Classes

Hi Richard, thanks for filling in for me there... I have now updated the chapter to make sense with Xcode 3.2.

Submitted by alex on Sun, 10/18/2009 - 09:57.
Creating Connections Problem

I have followed all the tutorials upto the point of creating the connections and I am now absolutely stuck. I am using XCode 3.2 on os x 10.6.1 I also have the iPhone SDK installed. When I add the NSObject in IB and select MAFoo as the class I do not see Class Actions or Class Outlets in the IB instead I see only the Class Identity, User Defined Runtime Attributes and Interface Runtime Attributes panels. I can't see where I have gone wrong. Can anyone offer me some help.

Thanks in advance

Chris

Submitted by Chris (not verified) on Sat, 09/12/2009 - 12:38.
Interface changes in Xcode 3.2

I had a hard time finding Class actions and Class outlets on the Identity inspector in Interface Builder 3.2. After browsing the net for info I found that these settings are now moved to the Library palette. Under Classes find your MAFoo class and set the actions and outlet(s) there.

Submitted by Bela Ujvary (not verified) on Wed, 09/09/2009 - 13:26.
x-code tutorial

Great tutorials! This is how to teach in simple terms so that people can grasp the concepts.
Exactly what i was looking for
Thank you and keep up good work.

I did have a question...

could the above action have been written like dot syntax

textField.text = @"five";

instead of

[textField setIntValue:5];

???

Submitted by nextEdge (not verified) on Tue, 08/11/2009 - 10:44.
Re: x-code tutorial

Hi nextEdge,

Dot syntax allows you to set the properties of objects, and was introduced in Leopard with Objective-C 2.0.

NSTextField is an old class, dating back to NeXTStep, and does not support properties, so the answer to your question is no.

It is easy to find out which classes allow you to use properties: they are well documented in the Xcode docs. It is mostly the newer classes introduced in Leopard that do so. You can also use them in any of your own classes in apps that are targeted at 10.5 or later.

Cheers,

Alex

Submitted by alex on Sun, 08/16/2009 - 10:38.
I'm having the same problem as Scott

Is there any solution to this issue yet? I'm using Xcode 3.1.2 and IB 3.1.2 (677)
Thanks, Ben

Submitted by Ben (not verified) on Thu, 02/26/2009 - 23:48.
Re: I'm having the same problem as Scott

Hi Ben,

Just drag the files to the Classes group.

Hope this helps,

Alex

Submitted by alex on Fri, 02/27/2009 - 04:34.
class creation problem

Alex,
It works now. Here is what I did:
I made sure the Class folder was highlighted in the Groups & Files pane in Xcode when I created the New File.
Also in Interface Builder when I went to Write Class Files somehow the language got changed to Ruby instead of Objective-C.
I changed it back to Objective-C and now everything works as described.
Thanks, Ben

Submitted by Ben (not verified) on Sun, 03/01/2009 - 21:02.
Generate code section

Hi, first I want to say thank you for the great tutorial. I have both a Mac and pc, and want to learn to program C and more complex object languages as well. Because of your great lesson, I have not given up on the Mac, although I was close before I stumbled upon it. :-)

I am having the same problem as Zeyad. I go to file, then write class files, and I chose rewrite the previous file in the project folder, yet xcode does not create anything in the Classes subfolder, the MAFoo.h and MAFoo.m remain in the resources subfolder. I have done this several times and feel I am following the directions word for word. I have used xcode 1.5 on my old laptop, the newest xcode version on a desktop, and the second most recent version on a friend's laptop, and cannot for the life of me get the class files to appear in the class subfolder. I tried closing both, restarting them, and then following the process again with no luck. I also went to File -> Synchronize With Xcode, (in the interface builder) and then followed the directions with no luck. I created my project folder on my desktop, and also tried creating it in my documents folder, but have still had no luck. I even just tried dragging the two files from the Resources folder to the Class folder out of frustration. Any ideas? I am completely at a loss as to what else I can possibly do…

Submitted by Scott (not verified) on Thu, 01/29/2009 - 07:50.
Generate Code section

Hi Scott,

Well, I've run through the tutorial, and the only thing I can see that I have forgotten is the reminder to save in IB before switching to Xcode. You mention that MAFoo.h and .m exist, have you checked whether they contain any code?

As for where they are located, in the Resources group, this is not really an issue. Simply drag them into the Classes group. It doesn't really make a difference to compilation either way.

Cheers

Alex

Submitted by alex on Thu, 01/29/2009 - 08:48.
Be sure to "Write Code" as "Objective C"

I had the same problem Scott. By default when I "Write Code" it wants to write it as "Ruby" which adds and extension, and therefore creates a file called MAFoo.h.rb, which of course doesn't overwrite MAFoo.h.

Try setting it to Objective C and it should work.

Submitted by Jason (not verified) on Sun, 06/07/2009 - 02:40.
Disaster recovery / prevention

How would one go about converting the code to objective-c after they had followed the examples and wound up with ruby?

And / OR

How do you ensure that it uses Objective-C the first go-Round?

Thanks so much, for any help.

Submitted by sidekick (not verified) on Wed, 07/08/2009 - 22:26.
Re: Disaster recovery / prevention

Hi Sidekick,

I have updated this chapter to make it clear that you need to select Objective-C, so hopefully that makes it clearer. I'm not sure why IB is setting Ruby as the default for some people.

All the best,

Alex

Submitted by alex on Thu, 07/09/2009 - 10:15.
No buttons or label

(Sorry Philip, I somehow managed to overwrite your comment instead of replying.)

It's easy to forget how confusing these things can be to the beginner. I reflexively save every 30 seconds (too many years working in OS 9 and QuarkXPress), so I often forget to mention saving in my tutorials.

Best,

Alex

Submitted by Philip Robar (not verified) on Mon, 01/26/2009 - 07:44.
No buttons or label

I've followed through and my code matches your exactly, but when i run my program there are not buttons and no text label in the window... Help?

Submitted by Jonathan Norrod (not verified) on Fri, 04/23/2010 - 15:40.
Err. pls help

Hi and thanks for this great great tutorial.

using Xcode 3.1.2

in Generate Code ,when follow : "Go to the File menu in Interface Builder and choose Write Class Files". and then go back to see the changes. i really see nothing changes. i have tried saving and building, but no use. and i tried to amend it manually but i also get some syntax error.

pls add a picture of this process or explain in more details if its not too much to ask.

Tx

Zeyad
Kuwait

Submitted by Zeyad Al-Mutairi (not verified) on Tue, 01/06/2009 - 00:01.
Re: Err pls help

Hi Zeyad,

When this happens, it may be that Interface Builder and Xcode have lost their "link" for some reason.

Try closing Interface Builder and Xcode, then reopen your Xcode project and double click on your MainMenu.xib (or nib) file in the Resources group. This should reestablish the connection.

Then repeat the instructions. Let me know if you are still having problems.

Cheers,

Submitted by alex on Wed, 01/07/2009 - 09:55.
great

I just want to say thank you again and again. problem is solved!:)

Submitted by Zeyad Al-Mutairi (not verified) on Wed, 01/07/2009 - 20:52.
Another Great Tutorial

I generally do not post feedback but I felt I owed you a big Thank you for taking your time to show us some basics.
This particular example has helped me tremendously. It also helps reading some books on Objective C to follow
just what's going on when IB writes out the class files.

Thank you!

T

Submitted by Anonymous (not verified) on Mon, 12/29/2008 - 04:09.
Does XCode 3.5 change some of the section 8 example?

When trying to follow along with this lesson (8) using the new XCode 3.5.1, when it comes to assigning a class (to the NSObject created in this lesson) from the pop-up menu (of the Inspector), my created Objective-C class ("MAFoo") doesn't show up on the list! I've tried several variations... and it just doesn't show up.

Submitted by Anonymous (not verified) on Sat, 12/20/2008 - 11:33.
Build

Hi,

It is important to Build your Xcode project before switching to Interface Builder. After you do this your IBAction method should show up. If it doesn't, make sure you included the :(id)sender argument.

Good luck!

Submitted by alex on Mon, 12/29/2008 - 08:25.
Seeking clarification (Tiger pdf )

Hi,
I'm very new to XCode (and Macs), however on p8.8 of the Tiger pdf, it states:
"Go to the MainMenu.nib window, and select the Classes tab. In the first column, you will see the NSObject class.
Select it and go to the Classes menu in the menubar. There, select Subclass NSObject."

Isn't NSObject the top dog? In any event I can't find a subclass NSObject - should it be another name?

Thanks nonetheless for a great resource...
Frank

Submitted by cervelo_oz on Sat, 11/22/2008 - 08:45.
Fantastic!!

I've just bought a Mac Mini (first Mac) and have spent the last week trying to trawl through the official Apple tutorial videos & help files which seem to be 90% marketing blurb about how fantastic XCode is blah blah blah.

I was almost at the point of giving up as I couldn't even pick up the basic concepts of using XCode and how IB / XCode etc linked together ... then I found your tutorials and I've learned more in the last half hour than the last week going through the Apple stuff. Clear, simple and in "laymans" terms absolutely fantastic!

Thanks for helping preserve my sanity!

Rob

Submitted by Anonymous on Sat, 08/30/2008 - 13:19.
Re: Fantastic!!

Hi Rob,

Yep, we think Cocoa should be simple to get into. Thanks for your comments.

Apple's documentation isn't that bad, once you get into the class descriptions, they are usually quite helpful. The Conceptual documents have been getting more marketing-oriented since around 10.4, but they still contain essential foundation concepts which every Cocoa dev needs to grasp. So hopefully, soon you'll be up and running to the point where they will become more palatable!

Cheers,

Alex

Submitted by alex on Mon, 09/15/2008 - 10:45.

Post new comment

The content of this field is kept private and will not be shown publicly.
Enter the code shown in the image:

CAPTCHA
This question is for testing whether you are a human visitor and to prevent automated spam submissions.
3 + 4 =
Solve this simple math problem and enter the result. E.g. for 1+3, enter 4.

Donate!





If you like what you find here and wish to support further development of this site, please donate via PayPal. No account required.

Syndicate

Syndicate content

User login

CAPTCHA
This question is for testing whether you are a human visitor and to prevent automated spam submissions.
1 + 18 =
Solve this simple math problem and enter the result. E.g. for 1+3, enter 4.
Enter the code shown in the image: