Apple Developer Connection
Member Login Log In | Not a Member? Contact ADC

< Previous PageNext Page > Hide TOC

Responder-Related Tasks

The following sections describe tasks related to the first-responder status of objects.

In this section:

Determining First-Responder Status
Setting the First Responder


Determining First-Responder Status

Usually an NSResponder object can always determine if it's currently the first responder by asking its window (or itself, if it's an NSWindow object) for the first responder and then comparing itself to that object. You ask an NSWindow object for the first responder by sending it a firstResponder message. For an NSView object, this comparison would look like the following bit of code:

if ([[self window] firstResponder] == self) {
      // do something based upon first-responder status
}

A complication of this simple scenario occurs with text fields. When a text field has input focus, it is not the first responder. Instead, the field editor for the window is the first responder; if you send firstResponder to the NSWindow object, an NSTextView object (the field editor) is what is returned. To determine if a given NSTextField is currently active, retrieve the first responder from the window and find out it is an NSTextView object and if its delegate is equal to the NSTextField object. Listing 3-8 shows how you might do this.

Listing 3-8  Determining if a text field is first responder

if ( [[[self window] firstResponder] isKindOfClass:[NSTextView class]] &&
   [window fieldEditor:NO forObject:nil] != nil ) {
        NSTextField *field = [[[self window] firstResponder] delegate];
        if (field == self) {
            // do something based upon first-responder status
        }
}

The control that a field editor is editing is always the current delegate of the field editor, so (as the example shows) you can obtain the text field by asking for the field editor's delegate. For more on the field editor, see "Text Fields, Text Views, and the Field Editor."

Setting the First Responder

You can programmatically change the first responder by sending makeFirstResponder: to an NSWindow object; the argument of this message must be a responder object (that is, an object that inherits from NSResponder). This message initiates a kind of protocol in which one object loses its first responder status and another gains it.

  1. makeFirstResponder: always asks the current first responder if it is ready to resign its status by sending it resignFirstResponder.

  2. If the current first responder returns NO when sent this message, makeFirstResponder: fails and likewise returns NO.

    A view object or other responder may decline to resign first responder status for many reasons, such as when an action is incomplete.

  3. If the current first responder returns YES to resignFirstResponder, then the new first responder is sent a becomeFirstResponder message to inform it that it can be the first responder.

  4. This object can return NO to reject the assignment, in which case the NSWindow itself becomes the first responder.

Figure 3-2 and Figure 3-3 illustrate two possible outcomes of this protocol.


Figure 3-2  Making a view a first responder—current view refuses to resign status

Making a view a first responder—current view refuses to resign status


Figure 3-3  Making a view a first responder—new view becomes first responder

Making a view a first responder—new view becomes first responder

Listing 3-9 shows a custom NSCell class (in this case a subclass of NSActionCell) implementing resignFirstResponder and becomeFirstResponder to manipulate the keyboard focus ring of its superclass.

Listing 3-9  Resigning and becoming first responder

- (BOOL)becomeFirstResponder {
    BOOL okToChange = [super becomeFirstResponder];
    if (okToChange) [super setKeyboardFocusRingNeedsDisplayInRect: [self bounds]];
    return okToChange;
}
 
- (BOOL)resignFirstResponder {
    BOOL okToChange = [super resignFirstResponder];
    if (okToChange) [super setKeyboardFocusRingNeedsDisplayInRect: [self bounds]];
    return okToChange;
}

You can also set the initial first responder for a window—that is, the first responder set when the window is first placed onscreen. You can set the initial first responder programmatically by sending setInitialFirstResponder: to an NSWindow object. You can also set it when you create a user interface in Interface Builder. To do this, complete the following steps.

  1. Control-drag from the window icon in the nib file window to an NSView object in the user interface.

  2. In the Connections pane of the inspector, select the initialFirstResponder outlet and click Connect.

After awakeFromNib is called for all objects in a nib file, NSWindow makes the first responder whatever was set as initial first responder in the nib file. Note that you should not send setInitialFirstResponder: to an NSWindow object in awakeFromNib and expect the message to be effective.



< Previous PageNext Page > Hide TOC


Last updated: 2007-03-16




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.
Get information on Apple products.
Visit the Apple Store online or at retail locations.
1-800-MY-APPLE

Copyright © 2007 Apple Inc.
All rights reserved. | Terms of use | Privacy Notice