Before it is displayed, a user interface item checks to see if its target implements
validateUserInterfaceItem:. If it does, then the enabled status of the item is determined by the return value of the method. You can therefore conditionally enable or disable an item by implementing
validateUserInterfaceItem: in the target object.
The Target Object
In some situations (typically if you set the target and action in Interface Builder), the target is the object to which the user interface item is connected directly; in other situations (when the user interface item’s target is
nil—such as if you connected it to First Responder in Interface Builder), the target is the first object in the responder chain that implements its action method. For more details, see “Responder Chain for Action Messages” in Cocoa Event Handling Guide > Event Architecture. In either case, the important thing to realize is that the target is the object that implements the user interface item’s action method. (The target is also the object that has the suitable context to know whether the action is appropriate.) Hence the object that must implement
validateUserInterfaceItem: is the same object that implements the action method.
For example, suppose you have a controller object that implements a
paste: method. When the
paste: method is invoked, it retrieves a value from the pasteboard and then pastes it into the current selection. It can only do this if there is a valid value on the pasteboard. The controller object therefore also implements
validateUserInterfaceItem: checks to see if the pasteboard contains useable data, and if it does it returns
YES otherwise it returns
NO. If the pasteboard does not contain useable data, the user interface item is disabled.
If in your application you have more than one controller that implements
paste:—each responsible for pasting different data—then each should have its own implementation of
validateUserInterfaceItem: that checks to see if the pasteboard contains data useable by it.
The implementation of
validateUserInterfaceItem: should follow these steps:
To decide whether or not an item should be enabled, you need to know what it will do if the user selects it. The sender implements the
NSValidatedUserInterfaceItemprotocol, so you can find out what tag and action are associated with it. You typically first therefore check to see what action is associated with the item (you need to test for each of the actions you’re interested in).
Checking the action rather than the tag means you avoid the fragility of having to remember to use the same tag for each user interface element that invokes the same method on the target.
If the action is something you’re interested in, then return a Boolean value appropriate for the current context.
If the action is not something you’re interested in, then either:
If your superclass implements the validation method (for example,
validateUserInterfaceItem:), invoke super’s implementation; otherwise
Return a default value (typically
The following example illustrates the implementation of
validateUserInterfaceItem: in a subclass of
- (BOOL)validateUserInterfaceItem:(id <NSValidatedUserInterfaceItem>)anItem
SEL theAction = [anItem action];
if (theAction == @selector(copy:))
if ( /* there is a current selection and it is copyable */ )
} else if (theAction == @selector(paste:))
if ( /* there is a something on the pasteboard we can use and
the user interface is in a configuration in which it makes sense to paste */ )
/* check for other relevant actions ... */
// subclass of NSDocument, so invoke super's implementation
return [super validateUserInterfaceItem:anItem];