0

I'm off to a good start. But I would like to make this code more dynamic.

NSMutableAttributedString *attString = [[NSMutableAttributedString alloc] initWithString:string];
UIFont *font = [UIFont systemFontOfSize:10.0f];
UIFont *smallFont = [UIFont systemFontOfSize:9.0f];

[attString beginEditing];
[attString addAttribute:NSFontAttributeName value:(font) range:NSMakeRange(0, string.length - 2)];

[attString addAttribute:NSFontAttributeName value:(smallFont) range:NSMakeRange(string.length - 1, 1)];

Say I have the following String:

@"C3OC2OH4"

I would like to adjust the font size of the numbers only to fulfill a chemistry application. How can I scan the above string, and create a series of custom ranges to plug into my function above, which adjusts the font size?

Jørgen R
  • 10,568
  • 7
  • 42
  • 59
JZ.
  • 21,147
  • 32
  • 115
  • 192
  • Why not use standard Unicode subscript characters: `@"C₃OC₂OH₄"`? – rmaddy Jul 12 '14 at 22:23
  • I build the formula from a function in my code, reading NSNumbers for the subscript portions. something like this: formulaString = [formulaString stringByAppendingString:[[firstAtom name] stringByAppendingString:chemicalRatio]]; How could I return unicode subscript characters for my NString *chemicalRatio? – JZ. Jul 12 '14 at 22:31
  • 1
    You could build a dictionary that maps numbers to their subscript representation. – rmaddy Jul 12 '14 at 22:37
  • See this solution: http://www.cannonade.net/blog.php?id=1467 – koen Jul 12 '14 at 23:37

1 Answers1

2

You can enumerate the characters and apply the attributes like this.

NSString * string = @"C3OC2OH4";

NSMutableAttributedString * attributedString = [NSMutableAttributedString new];

NSDictionary * subscriptAttributes = @{NSFontAttributeName : [UIFont systemFontOfSize:10.0],
                                       NSBaselineOffsetAttributeName : @(-5.0)};

[string enumerateSubstringsInRange:NSMakeRange(0, [string length])
                           options:NSStringEnumerationByComposedCharacterSequences
                        usingBlock:^(NSString *substring, NSRange substringRange, NSRange enclosingRange, BOOL *stop) {

                            NSCharacterSet * letterCharacterSet = [NSCharacterSet letterCharacterSet];

                            if ([substring rangeOfCharacterFromSet:letterCharacterSet].location != NSNotFound)
                                [attributedString appendAttributedString:[[NSAttributedString alloc] initWithString:substring]];
                            else
                                [attributedString appendAttributedString:[[NSAttributedString alloc] initWithString:substring attributes:subscriptAttributes]];

                        }];

In this case substring is each character and is appended without any change if it is a letter. If it is a number we change the font size and shift the baseline. Change them according to your need.

Good luck.

Desdenova
  • 5,326
  • 8
  • 37
  • 45
  • 1
    Nice answer. One suggestion. Move the creation of `subscriptAttributes` to the `else` block or to before the enumeration. Either create it once or just when needed. – rmaddy Jul 12 '14 at 23:24