Search code examples
objective-cios8nsattributedstringcore-textunderline

iOS - CFUnderline text in attributes of CFMutableAttributedString


Some propositions have emerged about this problem but it cannot be fixed. I try to underline (or even better to strikethrough) a text created for a PDF file. I use CF text like this:

+ (void)drawAllText:(NSString *)textToDraw inFrame:(CGRect)frameRect forTag:(NSInteger)tag {

CFMutableAttributedStringRef currentText = CFAttributedStringCreateMutable(kCFAllocatorDefault, 0);
CFAttributedStringReplaceString (currentText, CFRangeMake(0, 0), (CFStringRef) textToDraw);

NSDictionary *fontAttributes = [[NSDictionary alloc] init];
fontAttributes = [NSDictionary dictionaryWithObjectsAndKeys:
                      @"Verdana", (NSString *)kCTFontFamilyNameAttribute,
                      kCTUnderlineStyleSingle, (id)kCTUnderlineStyleAttributeName,
                      [NSNumber numberWithFloat:8.0], (NSString *)kCTFontSizeAttribute,
                      nil];
CTFontDescriptorRef descriptor = CTFontDescriptorCreateWithAttributes((CFDictionaryRef)fontAttributes);

Verdana and size 8.0 work fine but impossible to underline the text. I cannot neither change color (like [UIColor redColor].CGColor, (NSString *)kCTForegroundColorAttributeName).

Am I doing something wrong? Thanks!


Solution

  • Neither kCTUnderlineStyleAttributeName nor kCTForegroundColorAttributeName are font attributes. They don't belong in the dictionary you pass to CTFontDescriptorCreateWithAttributes(). The valid font attributes are listed in the CTFontDescriptor docs, here.

    kCTUnderlineStyleAttributeName and kCTForegroundColorAttributeName are attributes that can be applied in an attributed string. You could pass them to CFAttributedStringSetAttribute() or in the dictionary argument to CFAttributedStringSetAttributes(), etc.

    Finally, if you're going to put kCTUnderlineStyleSingle as a value in a dictionary, it needs to be wrapped in an NSNumber object. You can do that using a "boxing" expression such as @(kCTUnderlineStyleSingle).