ehsteve
ehsteve

Reputation: 77

Custom NSFormatter in Objective C

I am trying to write my own custom formatter in Objective C by subclassing NSNumberFormatter. Specifically what I'd like to do is make a number turn red if it is above or below certain values. The apple documentation says

For example, if you want negative financial amounts to appear in red, you have this method return a string with an attribute of red text. In attributedStringForObjectValue:withDefaultAttributes: get the non-attributed string by invoking stringForObjectValue: and then apply the proper attributes to that string.

Based on this advice I implemented the following code

- (NSAttributedString*) attributedStringForObjectValue: (id)anObject withDefaultAttributes: (NSDictionary*)attr;
{
    NSMutableAttributedString *attrString = [[NSMutableAttributedString alloc] initWithString:[self stringForObjectValue:anObject]];

    if ([[attrString string] floatValue] < -20.0f) {
        [attrString addAttribute:@"NSForegroundColorAttributeName" value:[NSColor redColor] range:NSMakeRange(0, 10)];
        return attrString;
    } else return attrString;
}

But when I test this all it does is freeze my application. Any advice would be appreciated. Thanks.

Upvotes: 0

Views: 545

Answers (2)

ehsteve
ehsteve

Reputation: 77

Here is how I was finally able to implement this. To make it more visible when a number is negative, I decided to make the background of the text red with white text. The following code does work in a NSTextField cell. I'm not sure why the code in my question (and the answer) does not work, addAttribute should work.

- (NSAttributedString *)attributedStringForObjectValue:(id)anObject withDefaultAttributes:  (NSDictionary *)attributes{

    NSString *string = [self stringForObjectValue:anObject];
    NSMutableAttributedString *attrString = [[NSMutableAttributedString alloc] initWithString:string];
    NSInteger stringLength = [string length];

    if ([[attrString string] floatValue] < 0)
    {
         NSDictionary *firstAttributes = @{NSForegroundColorAttributeName: [NSColor whiteColor],
                                      NSBackgroundColorAttributeName: [NSColor blueColor]};
    [attrString setAttributes:firstAttributes range:NSMakeRange(0, stringLength)];
}

return attrString;
}

Upvotes: 0

groomsy
groomsy

Reputation: 4955

I believe this has something to do with your NSRange that you create. I believe your length (10 in your example) is out of bounds. Try getting the length of the string that you use to initialize your NSMutableAttributedString.

For example:

- (NSAttributedString*) attributedStringForObjectValue: (id)anObject withDefaultAttributes: (NSDictionary*)attr;
{
    NSString *string = [self stringForObjectValue:anObject];
    NSMutableAttributedString *attrString = [[NSMutableAttributedString alloc] initWithString:string];
    NSInteger stringLength = [string length];

    if ([[attrString string] floatValue] < -20.0f)
    {
        [attrString addAttribute:@"NSForegroundColorAttributeName" value:[NSColor redColor] range:NSMakeRange(0, stringLength)];
    }

    return attrString;
}

Upvotes: 3

Related Questions