< Previous PageNext Page > Hide TOC

Building a Text Editor in 15 Minutes

This article shows how you can use Cocoa to create a simple but highly capable text editor in less than 15 minutes using Xcode and Interface Builder. The Cocoa document architecture provides many of the features required for this type of application automatically, requiring you to write a minimal amount of code.

Here is a simplified summary of the steps needed to complete this task:

You can build and test the application at several stages of completion. The following steps expand and explain this procedure. The steps assume that you have a basic acquaintance with Xcode and Interface Builder.

Contents:

Create the User Interface
Implement Document Archiving


Create the User Interface

This section shows how to use Xcode and Interface Builder to create the project and build its user interface.

  1. In Xcode, create a new Cocoa Document-based Application project.

  2. Open the MyDocument.nib file, which is in the Resources folder. Double-click the MyDocument.nib icon, which launches Interface Builder.

  3. Delete the label reading “Your document contents here” from the Window object. Drag an NSTextView object from the Cocoa-Text palette, which is shown in Figure 1. Resize the text view to almost fill the window, leaving margins as indicated by Interface Builder’s guide lines.

    Figure 1  Drag an NSTextView from the Cocoa Text Controls palette

    Drag an NSTextView from the Cocoa Text Controls palette
  4. Click once inside the text view and choose Show Inspector from the Tools menu to open the Inspector window. Choose Size from the pop-up menu, and set the view to resize with the window, by clicking on the inner set of crossed lines, which changes their appearance to springs, as shown in Figure 2.

    Note:  Clicking once inside the text view area selects the scroll view containing the text view, as indicated by the title of the Inspector window. Clicking twice inside the text view selects the text view itself. Be sure to set the resize characteristics of the scroll view.

    Figure 2  Set the resize characteristics of the scroll view

    Set the resize characteristics of the scroll view
  5. Choose Attributes from the pop-up menu of the Inspector window, and ensure that the following options are selected: Editable, Multiple fonts allowed, Undo allowed, Continuous Spell Checking, Uses Find Panel, and Show Scroller.

  6. Choose Test Interface from Interface Builder's File menu, and resize the window to ensure that the text view resizes properly along with the window. Note that you can already edit text in the text view. When you drag the NSTextView object from the Cocoa Text Controls palette, Interface Builder automatically instantiates all the Cocoa text objects required for a complete editing and layout implementation. Choose Quit Interface Builder to leave interface test mode (Interface Builder should continue running).

  7. Add a Format menu to the application. In Xcode, double-click the MainMenu.nib icon to open the MainMenu window, which represents the new application’s menu bar. From the Cocoa-Menus palette, drag a Format menu to the menu bar. Typically, a Format menu goes to the right of the Edit menu, as shown in Figure 3.

    Figure 3  Add a Format menu

    Add a Format menu
  8. Save both nib files and return to Xcode. Build and test the new application.

At this stage of your editor’s development, it has many sophisticated features. You should be able to enter, edit, cut, copy, and paste text. You can find and replace text using the Find window. You can undo and redo editing actions. You can also format text, setting its font, size, style, and color attributes. You can control text alignment, justification, baseline position, kerning, and ligatures. You can display a ruler that provides a graphical interface to manipulate many text and layout attributes, as well as setting tab stops. You can even use the spelling checker.

In addition to its many editing features, your editor can open multiple documents, each with its own text view and contents. What it lacks most prominently are the abilities to open files and save text in files (that is, archiving and unarchiving documents). It also lacks such features as displaying its name in its menu bar, having its own icon, and having useful information in its About window.

Quit your new application before proceeding to the next section.

Implement Document Archiving

This section explains how to enable your editor to open and save documents in files.

  1. Add an instance variable for the text view, so you can connect the text view with the code in your NSDocument subclass that handles archiving and unarchiving of documents in files. You also need to add an instance variable to hold the text string being edited (the document’s data model). Put the variable declarations in MyDocument.h as follows:

    #import <Cocoa/Cocoa.h>
    @interface MyDocument: NSDocument
    {
        IBOutlet NSTextView *textView;
        NSAttributedString *mString;
    }
    @end
  2. Initialize the string instance variable. Put the following lines in the init method (which has a stub implementation) in MyDocument.m:

        if (mString == nil) {
            mString = [[NSAttributedString alloc] initWithString:@""];
        }
  3. Write getter and setter methods for the string instance variable. Put them in MyDocument.m as follows:

    - (NSAttributedString *) string { return [[mString retain] autorelease]; }
     
    - (void) setString: (NSAttributedString *) newValue {
        if (mString != newValue) {
            if (mString) [mString release];
            mString = [newValue copy];
        }
    }
  4. Add method declarations for the getter and setter methods to the header file. MyDocument.h should now appear as follows:

    #import <Cocoa/Cocoa.h>
    @interface MyDocument: NSDocument
    {
        IBOutlet NSTextView *textView;
        NSAttributedString *mString;
    }
    - (NSAttributedString *) string;
    - (void) setString: (NSAttributedString *) value;
    @end
  5. From Xcode, drag the MyDocument.h file icon onto the Instances pane of MyDocument.nib, which is in Interface Builder. This step informs the MyDocument.nib file that the MyDocument interface now has an outlet variable named textView .

  6. In Interface Builder, click twice inside the text view to select the NSTextView object. Be sure you connect to the NSTextView and not its containing NSScrollView.

  7. Connect the textView outlet of the File's Owner by Control-dragging from the File's Owner icon in the Instances pane of MyDocument.nib to the text view in the window, as shown in Figure 4. Use the File's Owner Inspector to make the connection by double-clicking the textView outlet or by selecting the textView outlet and clicking the Connect button.

    Figure 4  Connect the text view outlet of the File's Owner

    Connect the text view outlet of the File's Owner
  8. In Interface Builder, make the File’s Owner (that is, the MyDocument object) the delegate of the text view. Double-click to select the text view in the window and Control-drag from the text view to the File’s Owner icon, as shown in Figure 5. Use the Connections pane of the NSTextView Inspector window to make the connection by double-clicking the delegate outlet or by selecting the delegate outlet and clicking the Connect button.

    Figure 5  Connect the delegate of the text view

    Connect the delegate of the text view
  9. Implement the text view’s delegate methodtextDidChange in MyDocument.m to synchronize the text string in the document’s data model (the mString instance variable) with the text storage belonging to the text view, whenever the user changes the text.

    - (void) textDidChange: (NSNotification *) notification
    {
        [self setString: [textView textStorage]];
    }
  10. Implement the archiving and unarchiving methods. When you initially created the project, Xcode placed stubs for these methods in MyDocument.m. Fill in the method bodies as follows:

    - (NSData *)dataRepresentationOfType:(NSString *)aType
    {
        NSData *data;
        [self setString:[textView textStorage]];
        data = [NSArchiver archivedDataWithRootObject:[self string]];
        return data;
    }
    - (BOOL)loadDataRepresentation:(NSData *)data ofType:(NSString *)aType
    {
        NSAttributedString *tempString = [NSUnarchiver unarchiveObjectWithData: data];
        [self setString:tempString];
        return YES;
    }

    Applications targeted for Mac OS X v10.4 or later systems should override dataOfType:error: and readFromData:ofType:error: instead of the methods shown in this step.

  11. Add one line of code to the windowControllerDidLoadNib method to place the contents of the window’s data model into the text view when the window’s nib file is initially loaded. Leave the call to the superclass windowControllerDidLoadNib method and add the following line after it:

    if ([self string] != nil) {
        [[textView textStorage] setAttributedString: [self string]];
    }
  12. Build and test your application.

Your editor should now be able to save documents that you create into files, and it should be able to open those documents again and continue editing them. If you attempt to close a document that has been changed since it was last saved, the editor displays a warning sheet and lets you save the document.

At this stage of its development, your editor opens and saves documents only with an extension of ????. To enable your application to save and open documents with a recognized file type, you need to use Xcode to configure the application’s document types settings as described in “Storing Document Types Information in the Application's Property List” in Document-Based Applications Overview. For complete details about application property lists, see Runtime Configuration Guidelines.

For more examples of Cocoa text applications, refer to the following URL:

http://developer.apple.com/samplecode/Cocoa/idxTextFonts-date.html

Additional examples, including source code for TextEdit, are contained in the following directory installed with Xcode Tools:

/Developer/Examples/AppKit/



< Previous PageNext Page > Hide TOC


© 1997, 2009 Apple Inc. All Rights Reserved. (Last updated: 2009-04-08)


Did this document help you?
Yes: Tell us what works for you.
It’s good, but: Report typos, inaccuracies, and so forth.
It wasn’t helpful: Tell us what would have helped.