On-the-fly text field formatting
On-the-fly text field formatting
- Subject: On-the-fly text field formatting
- From: Bill Cheeseman <email@hidden>
- Date: Sat, 14 Jul 2001 20:03:34 -0400
Mac OS X 10.0 added a new method to NSFormatter to enhance our ability to
edit a text field behind the user's back while the user is typing, and to
control where the insertion point or selection ends up after each keystroke.
The new method has the ungainly name:
- (BOOL)isPartialStringValid:(NSString **)partialStringPtr
proposedSelectedRange:(NSRangePointer)proposedSelRangePtr
originalString:(NSString *)origString
originalSelectedRange:(NSRange)origSelRange errorDescription:(NSString
**)error
I have figured out how to make it work (notwithstanding the absence of a
clear explanation in the NSFormatter reference document or the latest
Foundation release notes). But I would like a reality check on whether I'm
overlooking a simpler way to do it. There are two issues:
1. To alter what the user typed and make the altered text appear in the text
field, the release notes tell us to "replace" the string that is passed into
the method in the partialStringPtr parameter so as to pass the new string
back out, then return NO as the method result. The combination of a replaced
string and the NO return value signals Cocoa to display the altered text,
instead of rejecting it outright as the old method did when NO was returned,
or displaying exactly what the user typed when YES is returned.
What is meant by "replace" in the release notes? I can only make this work
by using the NSString copy method to alter the string; simply assigning a
new string to the existing pointer, or assigning a new pointer to the
existing handle, doesn't work. Is this correct?
2. Returning NO in this case does indeed place the altered string into the
text field, as advertised -- but it also calls my implementation of
NSControl's control:didFailToValidatePartialString:errorDescription:
delegate method. I assumed, when the release notes said that the altered
string would be displayed, that the delegate method would not be called. But
in fact the NO return value does trigger the delegate method. I guess there
could be circumstances where my application might want to know that it is
displaying something different from what the user typed.
I can't solve my problem by not implementing the delegate method. I need it
in order to catch and reject illegal characters as they are typed into the
text field; I present an alert sheet in that case. But I don't want to
present an alert sheet when the NSFormatter method returned NO just to
display an altered version of what the user typed.
So I need some way to signal the
control:didFailToValidatePartialString:errorDescription: method that it
shouldn't fire off an alert sheet in this circumstance. I can think of only
one way to do this: namely, to pass a dummy error string in the
errorDescription parameter. It doesn't have to be localized, since it will
never be displayed. It can be treated sort of like a notification name -- I
just have to document the fact that every client of my custom formatter must
obey a convention that, say, @"No Error" returned in the errorDescription
parameter signals that there is no error and that no alert sheet should be
presented.
This works, and it's pretty straightforward, but it seems like a misuse of
the errorDescription mechanism. Am I just being too fussy? Are there other
places in Cocoa where an errorDescription parameter is used more as a
signaling or notification mechanism than an error message generator? Is
there a constant declared somewhere to provide a standard way to interpret a
no-error errorDescription string?
--
Bill Cheeseman - email@hidden
Quechee Software, Quechee, Vermont, USA
The AppleScript Sourcebook - www.AppleScriptSourcebook.com
Vermont Recipes - www.stepwise.com/Articles/VermontRecipes