Volitans Software

A Current of Cocoa Code: Formatting a NSTextField

I’m starting a new series here: small Cocoa code examples. It will mostly cover cocoa problems that I could not find online; one I had to figure out. The first one is formatting of a NSTextField. In SMART Utility, I needed the user to enter a number for the maximum count of bad sectors that would trigger an error. Searching Google led no where. So I came up with the following code.

First, drag an NSTextField to a window. In your AppController, set an IBOutlet and link it to the NSTextField. Also, in the awakeFromNib method, add the following code:

	[[NSNotificationCenter defaultCenter
		addObserver:self 
		selector:@selector(textDidChange:)  
		name:NSControlTextDidChangeNotification 
		object:countTextFieldOutlet];

Set countTextField to whatever you called the IBOutlet above. Now, add this method:

- (void)textDidChange:(NSNotification *)aNotification

{

	NSText *countText = [[aNotification userInfo] objectForKey:@"NSFieldEditor"];

The code above gets the text object.

	NSTextField *countTextField = [aNotification object];

This gets the text field object.

	NSScanner *scanner;

	NSString *scanString;

	NSMutableString *returnString;

	if ([countText string]==NULL
		|| [countText string]==@""
		|| [[countText string] length]==0)
	{

		[countTextField setStringValue:@"0"];
		return;	
	}

If there is no text in the text field, set it to 0. This is the baseline.

	returnString=[[NSMutableString alloc] initWithCapacity:1000];

	scanner=[[NSScanner alloc] initWithString:[countText string]];

	do

	{

Okay, now it is going to scan the text for any decimal characters.

		scanString=NULL;

		[scanner scanCharactersFromSet: [NSCharacterSet decimalDigitCharacterSet
			intoString:&scanString];
		if (scanString!=NULL && scanString!=@"" && [scanString length]!=0)

			[returnString appendString:scanString];

Found a decimal character or characters, so add it to the appendString- a temporary string that will be set back to the text field.

		if (![scanner isAtEnd])

			[scanner setScanLocation:([scanner scanLocation]+1)];

If there are more characters, that means the scanner stopped at non decimal character. Skip over that character and continue scanning.

	}while(![scanner isAtEnd]);

Now that it is does scanning, prepare to put it back into the text field.

	if ([returnString intValue]<0)

		[returnString setString:@"0"];

If the integer value is 0 (even if its 00000), set text field to just a single 0.

	if ([returnString intValue]>1000)

		[returnString setString:@"1000"];

	if ([returnString length]==0)

		[returnString setString:@"0"];

The previous two if statements are the integer bounds. For this example, setting a number greater than 1000 or less than 0 is set to the max or min values respectively.

	[countTextField setStringValue:returnString];

Now that its done preparing, just set the text field to the temporary string.

	[returnString release];

	[scanner release];

}

That’s it. Its a pretty simple code. Get an example project here.