NSAttributedString - get font attributes
Asked Answered
K

4

11

I need to get info about my attributed string but can't figure out how. I'm getting this dictionary:

2013-11-04 18:06:10.628 App[1895:60b] {
    NSColor = "UIDeviceWhiteColorSpace 0.3 1";
    NSFont = "<UICTFont: 0x17d8d4c0> font-family: \".HelveticaNeueInterface-MediumP4\"; font-weight: bold; font-style: normal; font-size: 17.00pt";
    NSUnderline = 0;
}

It is easy to check the underline with:

[attrs objectForKey:@"NSUnderline"]

But how to get info about font like the font-style, font-weight etc.

Thanks for any help

Krug answered 4/11, 2013 at 17:11 Comment(3)
Where are you getting that dictionary from? It doesn't strike me as an attributed string.Clog
It looks like it might be the output for an attributesAtIndex: methodInstill
Yes, I get it from enumerateAttributesInRange methodKrug
T
15

You get the font from:

UIFont *font = attrs[NSFontAttributeName];

The issue is determining whether it is bold or not. There is no property for that. The only option is to look at the fontName of the font and see if contains "Bold" or some other similar term. Not all bold fonts have "Bold" in the name.

The same issue applies for determining of the font is italic or note. You have to look at the fontName and look for things like "Italic" or "Oblique".

Turney answered 4/11, 2013 at 17:17 Comment(5)
Even if I'm getting the dictionary above? I mean there is a property font-weight and font-style which is what I want. I just don't know an easy way to read it. So the informations are there the problem is how to read them.Krug
I believe @Krug is interested in using font.description to determine various font properties (font-weight, font-size etc). Font description is not meant for this, it may break in future.Unfortunate
There is no dictionary for the font. That is the output of the UIFont description.Turney
In the end I used this answer. It is easier to accomplish and as you say more reliable. ThanksKrug
OK but if you are only supporting iOS 7 (or later) then using UIFontDescriptor will be much easier and much more reliable. I wasn't aware of this new feature in iOS 7.Turney
U
4

UIFont has fontDescriptor starting iOS7 so you can try out that..

// Returns a font descriptor which describes the font.
    - (UIFontDescriptor *)fontDescriptor NS_AVAILABLE_IOS(7_0);

Usage:

// To get font size from attributed string's attributes
UIFont *font = attributes[NSFontAttributeName];
UIFontDescriptor *fontProperties = font.fontDescriptor;
NSNumber *sizeNumber = fontProperties.fontAttributes[UIFontDescriptorSizeAttribute];
NSLog(@"%@, FONTSIZE = %f",fontProperties.fontAttributes, [sizeNumber floatValue]);

Similar to UIFontDescriptorSizeAttribute you can find other traits like UIFontDescriptorFaceAttribute, UIFontDescriptorNameAttribute etc as mentioned in the docs.

Unfortunate answered 4/11, 2013 at 17:37 Comment(4)
I succesfully tried to do this: UIFontDescriptor *desc = [attrs objectForKey:@"NSFont"]; but when I want to log the fontAttributes dictionary it fails with unrecognized selector sent to instance. How to get these information from descriptor?Krug
@Krug You have to get the UIFont first like I showed in my answer. Then get the font descriptor as shown in this answer.Turney
Thanks @rmaddy, your answer helped me complete mine. I have edited my answer above to reflect the same.Unfortunate
@Unfortunate what does 'attributes' mean? I am not able to get the attributes of NSAttributedStringProof
F
0

You can see how to get info about your attributed string in this example that checks if a substring of the attributedText of a label is BOLD.

-(BOOL)isLabelFontBold:(UILabel*)label forSubstring:(NSString*)substring
{
    NSString* completeString = label.text;
    NSRange boldRange = [completeString rangeOfString:substring];
    return [self isLabelFontBold:label forRange:boldRange];
}

-(BOOL)isLabelFontBold:(UILabel*)label forRange:(NSRange)range
{
    NSAttributedString * attributedLabelText = label.attributedText;

    __block BOOL isRangeBold = NO;

    [attributedLabelText enumerateAttribute:NSFontAttributeName inRange:range options:0 usingBlock:^(UIFont *font, NSRange range, BOOL *stop) {
        if (font) {
            if ([self isFontBold:font]){
                isRangeBold = YES;
            }
        }
    }];

    return isRangeBold;
}

-(BOOL)isFontBold:(UIFont*)font
{
    UIFontDescriptor *fontDescriptor = font.fontDescriptor;
    UIFontDescriptorSymbolicTraits fontDescriptorSymbolicTraits = fontDescriptor.symbolicTraits;
    BOOL isBold = (fontDescriptorSymbolicTraits & UIFontDescriptorTraitBold) != 0;
    return isBold;
}
Footlights answered 29/3, 2016 at 10:58 Comment(0)
U
0

A update running iOS 10.0 swift 3.0 and the code Ashok solution has become something along these lines.

let fontDescription = focus.font?.fontDescriptor
let fontAttributes = fontDescription!.fontAttributes[kCTFontNameAttribute as String]!
Uncaredfor answered 20/12, 2016 at 13:11 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.