Online Book Reader

Home Category

Cocoa Programming for Mac OS X - Aaron Hillegass [105]

By Root 856 0
*)partial

newEditingString:(NSString **)newString

errorDescription:(NSString **)errorString

Here partial is the string, including the last keystroke. If your formatter returns NO, it indicates that the partial string is not acceptable. Also, if your formatter returns NO, it can supply the newString and an errorString. The newString will appear in the control. The errorString should give the user an idea of what she or he did wrong. If your formatter returns YES, the newString and the errorString are ignored.

Add the following method to ColorFormatter.m:

- (BOOL)isPartialStringValid:(NSString *)partial

newEditingString:(NSString **)newString

errorDescription:(NSString **)error

{

// Zero-length strings are OK

if ([partial length] == 0){

return YES;

}

NSString *match = [self firstColorKeyForPartialString:partial];

if (match) {

return YES;

} else {

if (error) {

*error = @"No such color";

}

return NO;

}

}

Build and run your application. You will not be able to type in anything except the color names.

Notice something annoying about this app: You can’t see what color would be chosen until you tab out of the field. What you would like is a formatter that does autocompletion. To enable autocompletion, you need to control the range of the selection as well. Comment out the isPartialStringValid:newEditingString:errorDescription: method and replace it with this method:

- (BOOL)isPartialStringValid:(NSString **)partial

proposedSelectedRange:(NSRange *)selPtr

originalString:(NSString *)origString

originalSelectedRange:(NSRange)origSel

errorDescription:(NSString **)error

{

// Zero-length strings are fine

if ([*partial length] == 0) {

return YES;

}

NSString *match = [self firstColorKeyForPartialString:*partial];

// No color match?

if (!match) {

return NO;

}

// If this would not move the beginning of the selection, it

// is a delete

if (origSel.location == selPtr->location) {

return YES;

}

// If the partial string is shorter than the

// match, provide the match and set the selection

if ([match length] != [*partial length]) {

selPtr->location = [*partial length];

selPtr->length = [match length] - selPtr->location;

*partial = match;

return NO;

}

return YES;

}

Build and run your application. Your formatter will now autocomplete color names as you type them.

Formatters That Return Attributed Strings


Sometimes, it is nice for the formatter to define not only the string that is to be displayed but also the attributes of that string. For example, a number formatter might print the number in red if it is negative. For this purpose, you will use NSAttributedString.

Your formatter can implement the following method:

- (NSAttributedString *)attributedStringForObjectValue:(id)anObj

withDefaultAttributes:(NSDictionary *)aDict

If the method exists, it will be called instead of stringForObjectValue:. The dictionary that you are passed contains the default attributes for the view where the data will be displayed. It is a good idea to merge the dictionary with your added attributes. For example, use the font from the text field where the data will be displayed, but make the foreground color red to show that the profits are negative.

Implement the following method to display the name of the color in that color:

- (NSAttributedString *)attributedStringForObjectValue:(id)anObj

withDefaultAttributes:(NSDictionary *)attributes

{

NSString *match = [self stringForObjectValue:anObj];

if (!match) {

return nil;

}

NSMutableDictionary *attDict = [attributes mutableCopy];

[attDict setObject:anObj

forKey:NSForegroundColorAttributeName];

NSAttributedString *atString

= [[NSAttributedString alloc] initWithString:match

attributes:attDict];

return atString;

}

Build and run the application. Note that the text field will not change colors until it gives up first-responder status.

For the More Curious: NSValueTransformer


Bindings read values from objects. Sometimes, a value will need some massaging before it can be used. To fulfill this purpose,

Return Main Page Previous Page Next Page

®Online Book Reader