The Cocoa text system implements a sophisticated editing mechanism that enables input of complex text character and style information. It is important to understand this mechanism if your code needs to hook into it.
The text system provides a number of control points where you can customize the editing behavior:
Text system classes provide methods to control many of the ways in which they perform editing.
You can implement more control through the Cocoa mechanisms of notification and delegation.
In extreme cases where the capabilities of the text system are not suitable, you can replace the text view with a custom subclass.
The Editing Environment
The Key-Input Message Sequence
Text View Delegation
Subclassing
Text editing is performed by a text view object. Typically, a text view is an instance of NSTextView
or a subclass. A text view provides the front end to the text system. It displays the text, handles the user events that edit the text, and coordinates changes to the stored text required by the editing process. NSTextView
implements methods that perform editing, manage the selection, and handle formatting attributes affecting the layout and display of the text.
NSTextView
has a number of methods that control the editing behavior available to the user. For example, NSTextView
allows you to grant or deny the user the ability to select or edit its text, using the setSelectable:
and setEditable:
methods. NSTextView
also implements the distinction between plain and rich text defined by NSText
with its setRichText:
and setImportsGraphics:
methods. See Text System User Interface Layer Programming Guide for Cocoa programming topic and the NSTextView
and NSText
class specifications for more information.
An editable text view can operate in either of two distinct editing modes: as a normal text editor or as a field editor. A field editor is a single text view instance shared among all the text fields belonging to a window in an application. This sharing results in a considerable performance gain because a text view is a heavyweight object. When a text field becomes the first responder, the window inserts the field editor in its place in the responder chain. A normal text editor accepts Tab and Return characters as input, whereas a field editor interprets Tab and Return as cues to end editing. The NSTextView
method setFieldEditor:
controls this behavior.
When you want to modify the way in which Cocoa edits text, it’s helpful to understand the message sequence that defines the editing mechanism, so you can select the most appropriate point at which to add your custom behavior.
The message sequence invoked when a text view receives key events involves four methods declared by NSResponder
. When the user presses a key, the operating system handles certain reserved key events and sends others to the NSApplication
object, which handles Command-key events. The application object sends other key events to the key window, which handles Control-key events and sends other key events to the first responder. Figure 1 illustrates this sequence.
If the first responder is a text view, the key event enters the text system. The key window sends the text view a keyDown:
message with the event as its argument. The keyDown:
method passes the event to interpretKeyEvents:
, which sends the character input to the input manager for key binding and interpretation. In response, the input manager sends either insertText:
or doCommandBySelector:
to the text view. Figure 2 illustrates the sequence of text-input event processing.
For more information about text-input key event processing, see Text Input Management and “Text System Defaults and Key Bindings.”
When the text view has enough information to specify an actual change to its text, it sends an editing message to its NSTextStorage
object to effect the change. The methods that change character and attribute information in the text storage object are declared in the NSTextStorage
superclass NSMutableAttributedString
, and they depend on the two primitive methods replaceCharactersInRange:withString:
and setAttributes:range:
. The text storage object then informs its layout managers of the change to initiate glyph generation and layout when necessary, and it posts notifications and sends delegate messages before and after processing the edits. For more information about the interaction of text view, text storage, and layout manager objects, seeText Layout Programming Guide for Cocoa.
Delegation provides a powerful mechanism for modifying editing behavior because you can implement methods in the delegate that can then perform editing commands in place of the text view, a technique called delegation of implementation. NSTextView
gives its delegate this opportunity to handle a command by sending it a textView:doCommandBySelector:
message whenever it receives a doCommandBySelector:
message from the input manager. If the delegate implements this method and returns YES
, the text view does nothing further; if the delegate returns NO
, the text view must try to perform the command itself.
Before a text view makes any change to its text, it sends its delegate a textView:shouldChangeTextInRange:replacementString:
message, which returns a Boolean value. (As with all delegate messages, it sends the message only if the delegate implements the method.) This mechanism provides the delegate with an opportunity to control all editing of the character and attribute data in the text storage object associated with the text view.
For more information about text view delegation, see “Delegate Messages and Notifications.”
Using NSTextView
directly is the easiest way to interact with the text system, and its delegate mechanism provides an extremely flexible way to modify its behavior. In cases where delegation does not provide required behavior, you can subclass NSTextView
. See “Subclassing NSTextView” for more information on how to implement a subclass of NSTextView
.
Note: To modify editing behavior, your first resort should be to notification or delegation, rather than subclassing. It may be tempting to start by trying to subclass NSTextView
and override keyDown:
, but that’s usually not appropriate, unless you really need to deal with raw key events before input management or key binding. In most cases it’s more appropriate to work with one of the text view delegate methods or with text view notifications.
A strategy even more complicated than subclassing NSTextView
is to create your own custom text view object. If you need more sophisticated text handling than NSTextView
provides, for example in a word processing application, it is possible to create a text view by subclassing NSView
, implementing the NSTextInput
protocol, and interacting directly with the input management system. For information on creating custom text views, see “Creating Custom Views.” Also refer to the reference documentation for NSText
, NSTextView
, NSView
, and the NSTextInput
protocol.
© 2003, 2008 Apple Inc. All Rights Reserved. (Last updated: 2008-02-08)