4ntoine
4ntoine

Reputation: 20420

NSAttributedString: underline is not applied

I'm trying to add underline style for UITextView and it's not applied. If i use "shadow" (uncomment shadow styling and comment underline styling) i can see it, but no underline is applied for some reason. I use "Courier New" font.

- (void) addDiagHighlighting: (NSMutableAttributedString*)attrString start:(int)start end:(int)end severity:(int)severity {
    // ignore diags that are out of bounds
    if (start > attrString.length || end > attrString.length)
        return;

    NSRange range = NSMakeRange(start, end - start);
    UIColor *diagColor = [self getSeverityColor: severity];

    // shadow
//    NSShadow *shadow = [[NSShadow alloc] init];
//    [shadow setShadowColor: diagColor];
//    [shadow setShadowOffset: CGSizeMake (1.0, 1.0)];
//    [shadow setShadowBlurRadius: 1.0];
//    [attrString addAttribute:NSShadowAttributeName
//                       value:shadow
//                       range:range];

    // underline
    [attrString addAttributes:@{
                                NSUnderlineColorAttributeName : diagColor, // color
                                NSUnderlineStyleAttributeName : @(NSUnderlinePatternSolid) // style
                                }
                       range:range];
}

i can change adding attributes to adding both shadow and underling and i can see shadow but still no underline:

// shadow + underline
[attrString addAttributes:@{
                            NSShadowAttributeName : shadow, // shadow
                            NSUnderlineColorAttributeName : diagColor, // color
                            NSUnderlineStyleAttributeName : @(NSUnderlinePatternSolid) // style
                            }
                   range:range];

Upvotes: 5

Views: 3647

Answers (2)

Imanou Petit
Imanou Petit

Reputation: 92599

The Apple Developer Documentation states about NSUnderlineStyle:

The style, pattern, and optionally by-word mask are OR'd together to produce the value for underlineStyle and strikethroughStyle.

Therefore, with Swift 5 and iOS 12.3, you can use the bitwise OR operator (|) to set a style and a pattern together for NSAttributedString.Key.underlineStyle attribute.


The following Playground sample code shows how to set both NSUnderlineStyle.thick and NSUnderlineStyle.patternDot attributes for a NSAttributedString instance:

import UIKit
import PlaygroundSupport

let attributes = [NSAttributedString.Key.underlineStyle : (NSUnderlineStyle.thick.rawValue | NSUnderlineStyle.patternDot.rawValue)]
let attributedString = NSAttributedString(string: "Some text", attributes: attributes)

let label = UILabel(frame: CGRect(x: 0, y: 0, width: 200, height: 40))
label.backgroundColor = .white
label.attributedText = attributedString

PlaygroundPage.current.liveView = label

Upvotes: 6

anthonyliao
anthonyliao

Reputation: 1314

You need to OR a NSUnderlinePattern with an NSUnderlineStyle to get it working (see Apple documentation here)

Try this:

[attrString addAttributes:@{
                        NSShadowAttributeName : shadow, // shadow
                        NSUnderlineColorAttributeName : diagColor, // color
                        NSUnderlineStyleAttributeName : @(NSUnderlineStyleSingle | NSUnderlinePatternSolid) // style
                        }
               range:range];

Or with dots...

[attrString addAttributes:@{
                        NSShadowAttributeName : shadow, // shadow
                        NSUnderlineColorAttributeName : diagColor, // color
                        NSUnderlineStyleAttributeName : @(NSUnderlineStyleSingle | NSUnderlinePatternDot) // style
                        }
               range:range];

Upvotes: 7

Related Questions