Online Book Reader

Home Category

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

By Root 783 0
the substring is not found, the length will be 0.

Implement the Basic Formatter Methods


Edit ColorFormatter.m to look like this:

#import "ColorFormatter.h"

@interface ColorFormatter ()

- (NSString *)firstColorKeyForPartialString:(NSString *)string;

@end

@implementation ColorFormatter

- (id)init

{

self = [super init];

if (self) {

colorList = [NSColorList colorListNamed:@"Apple"];

}

return self;

}

- (NSString *)firstColorKeyForPartialString:(NSString *)string

{

// Is the key zero-length?

if ([string length] == 0) {

return nil;

}

// Loop through the color list

for (NSString *key in [colorList allKeys]) {

NSRange whereFound = [key rangeOfString:string

options:NSCaseInsensitiveSearch];

// Does the string match the beginning of the color name?

if ((whereFound.location == 0) && (whereFound.length > 0)) {

return key;

}

}

// If no match is found, return nil

return nil;

}

- (NSString *)stringForObjectValue:(id)obj

{

// Not a color?

if (![obj isKindOfClass:[NSColor class]]) {

return nil;

}

// Convert to an RGB Color Space

NSColor *color;

color = [obj colorUsingColorSpaceName:NSCalibratedRGBColorSpace];

// Get components as floats between 0 and 1

CGFloat red, green, blue;

[color getRed:&red

green:&green

blue:&blue

alpha:NULL];

// Initialize the distance to something large

float minDistance = 3.0;

NSString *closestKey = nil;

// Find the closest color

for (NSString *key in [colorList allKeys]) {

NSColor *c = [colorList colorWithKey:key];

CGFloat r, g, b;

[c getRed:&r

green:&g

blue:&b

alpha:NULL];

// How far apart are 'color' and 'c'?

float dist;

dist = pow(red - r, 2) + pow(green -g, 2) + pow(blue - b, 2);

// Is this the closest yet?

if (dist < minDistance) {

minDistance = dist;

closestKey = key;

}

}

// Return the name of the closest color

return closestKey;

}

- (BOOL)getObjectValue:(id *)obj

forString:(NSString *)string

errorDescription:(NSString **)errorString

{

// Look up the color for 'string'

NSString *matchingKey = [self firstColorKeyForPartialString:string];

if (matchingKey) {

*obj = [colorList colorWithKey:matchingKey];

return YES;

} else {

// Occasionally, 'errorString' is NULL

if (errorString != NULL) {

*errorString = [NSString stringWithFormat:

@" is not a color", string];

}

return NO;

}

}

@end

Build and run your application. You should be able to type in color names and see the background of the BigLetterView change accordingly. Also, if you use the color well, you should see the name of the color change in the text field. Try typing in a string that is not a color.

The Delegate of the NSControl Class


Note that the bindings mechanism makes a nice Alert sheet when the formatting fails. The text field’s delegate can also be informed of the failed formatting. If the formatter decides that the string is invalid, the delegate is sent the following error message:

- (BOOL)control:(NSControl *)control

didFailToFormatString:(NSString *)string

errorDescription:(NSString *)error

The delegate can override the opinion of the formatter. If it returns YES, the control displays the string as is. If it returns NO, the delegate agrees with the formatter: The string is invalid.

Implement the following method in TutorController.m:

- (BOOL)control:(NSControl *)control

didFailToFormatString:(NSString *)string

errorDescription:(NSString *)error

{

NSLog(@"TutorController told that formatting of %@ failed: %@",

string, error);

return NO;

}

Now open MainMenu.xib and make the TutorController the delegate of the text field (Figure 26.9).

Figure 26.9. Connect the Text Field’s delegate Outlet

Build and run your application. When validation fails, you will see a message on the console indicating what the string was and why it failed.

Checking Partial Strings


You might want to create a formatter that prevents the user from typing letters that are not part of a color name. To make the formatter check the string after every keystroke, implement the following method:

- (BOOL)isPartialStringValid:(NSString

Return Main Page Previous Page Next Page

®Online Book Reader