Anda di halaman 1dari 7

First and foremost, make sure you have the developer tools, which you can get with

a free
account from ADC. After installation, browse to your /Developer/Applications folder and
find Xcode, and open it.
After you open it, you should be presented with a simple setup assistant (use default settings)
as well as a "welcome screen" which can be safely closed out (or you can browse around it if
you feel the need to). Go to File->New Project (Shift - Command - N), and select Cocoa
Application.
In the next screen, name the project "My Cocoa Application" and press Finish. If you didn't
change the directory of the project at that screen, it's default location is ~/<Project Name>
(expanded: /Users/<user>/<Project Name>).
Now you are presented with the main Xcode window. On the left column is a list of all
relevant files: classes, which contain the classes of your project, other sources, such as the
main.m and prefix headers, resources, which include the interface document (MainMenu.nib
in this case), required frameworks, and products (the outcome of compiling your project, in
this case My Cocoa Application.app). The Target is the group of all files that make the
product.
Classes are similar to the source files of any application, however they can be used
interactively with each other. A method, which you will here about, is basically a function in
a class. A method is also a message sent to a class. A function can be called repeatedly from
different areas of code to do a repetitive set of instructions.

The first thing we want to do here is create a new class for controlling the program, aptly
named "Controller." Right click the Classes folder in the file list, and select Add->New File.
In the resulting window, select "Objective-C Class" from the list. In the next section, enter
"Controller" as the file name, and click Finish without changing any settings.
Now you should have had a new window open up, just close out of it. Right now we don't
need to edit any of these files. Now we can get on to making the interface. The interface file
is a .NIB file, which means NeXT Interface Builder. Un-disclose the "Resources" group in
the file list, and double click MainMenu.nib. Interface Builder, an app bundled with the
Developer Tools should now open up. At first you are presented with an empty window, a
document window listing the elements in the NIB, and a MainMenu bar. The empty window
is simply the window for your application, which as it is now doesn't have anything in it.
The Main Menu bar above is the same menu bar that will appear at the top of your screen
when your app is running. To make it say other than "NewApplication," double-click that
area, and type in "Cocoa Application." Now single-click the same spot, to open the menu.
Double-click each menu item to change it's name to match the application we're making. You
can also do the same for the item in the Help menu.
The Menu Bar's modification is complete, so you can close that window. Now we can add
some parts to the main window. Controls, or things you can interact with in a window
(buttons, sliders, lists, etc) are stored in the Library Palette. To bring up this palette, do Shift Command - L. You should see a grid of different controls you can put in your window, and
you can simply drag and drop them in. Let's drag a slider (NSSlider) and two text boxes

(NSTextField). Also drag two buttons (NSButton).


It really doesn't matter how you arrange the controls. You can put them where ever you want
to. I do suggest putting one text box directly next to one button, and you'll see why a bit
onwards.
Now hit Command - Shift - I (I as in Interface) to bring up the inspecter. Here you can adjust
settings for individual controls like the ones you just dragged in. Make sure you have the first
tab of the Inspector selected (look just below the palette title). We will change the names of
the buttons, and there are two ways to do this: one is to double click the text on the button
itself, and two is to do it through the inspector. I will simply double click the text on the
button, and edit it so my left button says "Set to:" and my right button says "Reset." Select the
two text field items on the window (shift - click each item), and head to the Inspector. If
items are of the same class (in this case, NSTextField), you can edit attributes simultaneously.
I want to make mine a bit nicer looking, so I will change the ends of the boxes to rounded. Do
this by selecting the last tab under the Border header.
Now you're text boxes should be nice looking and rounded, but there's something we are
going to want to do with the box next to the "Set to:" button, and that's add a number
formatter. A formatter only makes certain text enterable into a text field, and we want this to
be 0-100 for this box. Drag an NSNumberFormatter (the square with the money sign) from
the Library right onto that text field next to the button. Now if you select the text field, a little
circle should appear under it with a money sign in a square on it. Click this to bring up the
formatter attributes in the Inspector.
In the Inspector, there should be a drop-down box a the very top that says "Mac OS X 10.4+,"
but for ease-of-use, click this and select "Mac OS X 10.0+." Now you should clearly see
presets on the bottom and some settings up top. In the presets list, select the item with 100
under the "Positive" column and -100 under the "Negative" column. In the "Minimum" text
box, enter 0, and in the "Maximum" text box, enter 100. This text field now only accepts
whole numbers between 0 and 100.
However, it doesn't do anything right now, except format the number box. By adding code,
we can change that, and make it do a very simple task. Go back to the Xcode window now,
and find your Controller.h file in the file list. What you need to do here is kind of tricky at
first, but very easy to understand after you do it the first time. Controller is a subclass (a
"branch-off") of the main superclass, NSObject. Every class in Cocoa is an NSObject at it's
root. Right now, we need to instantiate Controller in our NIB file to allow it to interact with
the controls in the future. Instantiating is, sort of, when you make a usable "copy" of an
object that can send and receive messages. Remember that methods (basically functions) can
be messages.
So, we need to drag our header file (Controller.h) in the Document window of our
MainMenu.nib file. If you haven't already, re-open MainMenu.nib in interface builder, and
make sure the document window is showing (look below to see the document window). Keep
Interface Builder active ("on top" of every other window), but make sure you can see the file
list in Xcode's window behind it. Click the "H" icon directly to the left of the Controller.h file
in Xcode for a few second, then drag it into the document window. When hovering over the
document window, you should see the add cursor (the one with the green plus). When you
drop it in nothing will happen.

We need to actually instantiate the Controller class now. Do this by dragging an NSObject
(the plain blue cube) item from the Library palette straight into the document window.
Open the Inspector Palette (Command - Shift - I), and go to the Classes tab at the very top.
The Classes tab is the dark blue circle with the white "i" on it. You will see a label that says
"Class" with a drop-down box right next to it. In this drop-down box, type in the name of the
class you want it to be in this case the one we just instantiated - Controller. You will need
to instantiate custom classes before using them in this way.
Now you have a working instance of the controller class. Onto the next step, which actually
involves coding, finally. Don't close IB (Interface Builder) yet, though, we will need it soon
enough.
Go back to Xcode, and in the file list, select Controller.h. Go to View -> Zoom Editor In to
open up the in-window editor (or do Shift - Command - E). Right now in this header file you
should have this exactly:
#import <Cocoa/Cocoa.h>
@interface Controller : NSObject {
}
@end

Because this class will be interacting with the NIB file, we need to add IBOutlets, which
allow you to connect this object to some on-screen controls. For this, the IBOutlet type will
be id, which can stand for any object. Edit the header file (Controller.h) to look like this:
#import <Cocoa/Cocoa.h>
@interface Controller : NSObject {
IBOutlet id textField;
IBOutlet id slider;
IBOutlet id setToAmountField;
}
@end

Now you have three outlets in interface builder you can connect to the object. We still need to
make our methods, though. A method generally takes the following form:
-(<RETURN TYPE>)doThis:(id)arg1 andThis:(id)arg2; // (etc many arguments, or no arguments)

there can be

<RETURN TYPE> is the type of variable you want the method to return. For this application,
we will be using void which doesn't return anything. id is a variable type that, as you read,
stood for any object. You can replace it with some sort of variable that is the only variable or
class that can be passed into the method:
-(void)doThis:(NSString *)arg1 andThis:(NSString *)arg2;

The above method returns nothing, and can only take NSStrings as arguments.
There is a special kind of method setup for methods that are activated from an interface (with
controls, etc):

-(IBAction)doThis:(id)sender;

IBAction is just a notational way of doing void, but the (id)sender piece is required for
Interface Builder to properly connect the actions (methods). So... let's make a method.
The first method we want to do is a reset method, to reset everything back to zero, which will
be triggered by the Reset button. We also want to make a set-to method, but remember,
IBActions can only take one argument (sender). So we'll need to make two methods to
accomplish that. Edit your header file to look like this:
#import <Cocoa/Cocoa.h>
@interface Controller : NSObject {
IBOutlet id textField;
IBOutlet id slider;
IBOutlet id setToAmountField;
}
-(IBAction)reset:(id)sender;
-(IBAction)setToButtonClicked:(id)sender;
-(void)setAllTo:(int)numberToSetTo;
@end

The setToButtonClicked: method will later trigger the setAllTo: method. Right now, we can
hook these things up in Interface Builder. Connecting outlets and actions simply requires
Control - dragging from one object to another. To set one of objectA's outlets to objectB, you
drag from objectA to B. To have objectB activate one of objectA's methods, you drag from B
to A. Let's set the outlets of the Controller object. Go to interface builder, and control drag
from the blue Controller cube in the document window to the top text field, and in the
resulting HUD window, select the "textField" outlet. Do the same for the slider, and the
setToAmountField, which will be the text field right next to the Set To: button.
Of course, now we want to hook up our actions/methods. To do this, drag from the object that
will trigger the action to the Controller object, and select the proper action. For the Reset
button, select the reset: action, and for the Set to: button, select the setToButtonClicked:
action.
For the extent that this tutorial goes, the interface is done. You can close IB. However, it's not
a polished interface and some features that would be expected are missing. Head back to
Xcode. Copy those three methods we wrote in Controller.h to Controller.m, under
@implementation Controller so it looks like this:
#import "Controller.h"
@implementation Controller
-(IBAction)reset:(id)sender
{
}
-(IBAction)setToButtonClicked:(id)sender
{
}
-(void)setAllTo:(int)numberToSetTo
{
}
@end

Be sure to remove the semicolons from the end of those lines (just those lines). This .m file,
or implementation file, is where the instructions are mainly stored. Our header file tells us we
have these methods, and the implementation file shows us what they do.
Cocoa is full of predefined classes, 3 of which we have in our program here (NSSlider,
NSTextField, NSButton). These classes each have their own methods you can use to do
something to the class. Methods are sent in this fashion:
[receiver doThis:withTheseArgs];

or if there are no arguments:


[receiver doSomething];

The receiver is the object getting the message (doThis: and doSomething in these cases). We
are going to have three objects that need to be sent messages: slider, textField, and
setToAmountField. For slider and text field, we will be using one method (it works for both
classes - most classes do not share most methods): setIntValue:. It does just what it seems
like, it sets the integer value of the receiver. setToAmountField will be getting a different
message: intValue. Instead of setting the intValue, it gets it from the receiver. Let's look at
our reset: method.
We want this method to reset everything back to 0, so we will somehow be using
setIntValue:0 somewhere. There are two objects that will receive this: slider and textField.
Let's implement that under the method in the implementation file:
#import "Controller.h"
@implementation Controller
-(IBAction)reset:(id)sender
{
[slider setIntValue:50];
[textField setIntValue:50];
}
-(IBAction)setToButtonClicked:(id)sender
{
}
-(void)setAllTo:(int)numberToSetTo
{
}
@end

As you can see, it tells the slider and the textField to set their values to 50. However, we want
the user to be able to set it to a custom amount, which is what the other two methods are for.
We want the setButtonClicked: method to simply call the other method, setAllTo:, with an
argument (because IBActions cannot take any arguments other than sender). Since the
setAllTo: method is within the same class, we use self as the receiver. But remember, we
want to pass an argument that's the int value of the setToAmountField text field. So, what do
we do? Well, we call another method, as you read: intValue. This can all be done in one line
by separating with brackets, the standard Objective-C convention:
#import "Controller.h"
@implementation Controller
-(IBAction)reset:(id)sender

{
[slider setIntValue:50];
[textField setIntValue:50];
}
-(IBAction)setToButtonClicked:(id)sender
{
[self setAllTo:[setToAmountField intValue]];
}
-(void)setAllTo:(int)numberToSetTo
{
}
@end

That one line really calls two methods, and passes the result of one as the argument of
another. It doesn't do anything, yet, because setAllTo: is empty. We can basically use the
same code as reset: with a slight change, and that's using the passed argument:
numberToSetTo:
#import "Controller.h"
@implementation Controller
-(IBAction)reset:(id)sender
{
[slider setIntValue:50];
[textField setIntValue:50];
}
-(IBAction)setToButtonClicked:(id)sender
{
[self setAllTo:[setToAmountField intValue]];
}
-(void)setAllTo:(int)numberToSetTo
{
[slider setIntValue:numberToSetTo];
[textField setIntValue:numberToSetTo];
}
@end

However, the number formatter we did earlier does not work if the method simply grabs
whatever is in the text field at the time. So, we need to do an ifelse statement to determine
if the value is greater or equal than 0 or less than or equal to 100.
#import "Controller.h"
@implementation Controller
-(IBAction)reset:(id)sender
{
[slider setIntValue:50];
[textField setIntValue:50];
}
-(IBAction)setToButtonClicked:(id)sender
{
[self setAllTo:[setToAmountField intValue]];
}
-(void)setAllTo:(int)numberToSetTo
{
if(numberToSetTo >= 0 && numberToSetTo <= 100)
{
[slider setIntValue:numberToSetTo];
[textField setIntValue:numberToSetTo];
}

else
}
@end

As that is, it doesn't do anything at all if it's less than 0 or greater than 100, which would be
confusing. So, we are going to do something really easy to fix that. Right now, if you build
your application (with the Build and Go button in the toolbar), it will work, so you've made a
Cocoa app.
Change your code to this:
#import "Controller.h"
@implementation Controller
-(IBAction)reset:(id)sender
{
[slider setIntValue:50];
[textField setIntValue:50];
}
-(IBAction)setToButtonClicked:(id)sender
{
[self setAllTo:[setToAmountField intValue]];
}
-(void)setAllTo:(int)numberToSetTo
{
if(numberToSetTo >= 0 && numberToSetTo <= 100)
{
[slider setIntValue:numberToSetTo];
[textField setIntValue:numberToSetTo];
}
else NSBeep();
}
@end

else NSBeep(); means that if the value is not greater than 0 or less than 100, it will just make
a beep noise. NSBeep() is not a normal method, it's a global C function that can be called
from anywhere.

Anda mungkin juga menyukai