How can I both stroke and fill with NSAttributedString w/ UILabel
Asked Answered
O

5

40

Is it possible to apply both stroke and fill with an NSAttributedString and a UILabel?

Oneness answered 16/4, 2013 at 22:1 Comment(0)
O
100

Yes, the key is to apply a Negative value to the NSStrokeWidthAttributeName If this value is positive you will only see the stroke and not the fill.

Objective-C:

self.label.attributedText=[[NSAttributedString alloc] 
initWithString:@"string to both stroke and fill" 
attributes:@{
             NSStrokeWidthAttributeName: @-3.0,
             NSStrokeColorAttributeName:[UIColor yellowColor],
             NSForegroundColorAttributeName:[UIColor redColor]
             }
];

Thanks to @cacau below: See also Technical Q&A QA1531

Swift 4 version:

let attributes: [NSAttributedStringKey : Any] = [.strokeWidth: -3.0,
                                                 .strokeColor: UIColor.yellow,
                                                 .foregroundColor: UIColor.red]

label.attributedText = NSAttributedString(string: text, attributes: attributes)

Swift 5.1 version:

let attributes: [NSAttributedString.Key : Any] = [.strokeWidth: -3.0,
                                                  .strokeColor: UIColor.yellow,
                                                  .foregroundColor: UIColor.red]

label.attributedText = NSAttributedString(string: text, attributes: attributes)
Oneness answered 16/4, 2013 at 22:1 Comment(6)
Note that the "outline" will be a inner outline, not an outer one - i.e. the outline will eat into the fill area.Marvelmarvella
@Marvelmarvella is there a way to generate a fill "outside" with UILabel + AttributedText?Oneness
AWESOME! Thanks for the tip. This saved me a ton of time!Evocative
See also Technical Q&A QA1531Brutish
Thanks, when I first saw negative values for that key I was wondering why. I set a positive value instead and got a stroke with no fill before I came upon this answer.Loya
good answer! this helped me today.Souza
W
8

Swift version:

let attributes = [NSStrokeWidthAttributeName: -3.0,
                      NSStrokeColorAttributeName: UIColor.yellowColor(),
                      NSForegroundColorAttributeName: UIColor.redColor()];

label.attributedText = NSAttributedString(string: "string to both stroke and fill", attributes: attributes)

Swift 3 version:

    let attributes = [NSStrokeWidthAttributeName: -3.0,
                      NSStrokeColorAttributeName: UIColor.yellow,
                      NSForegroundColorAttributeName: UIColor.red] as [String : Any]

    label.attributedText = NSAttributedString(string: "string to both stroke and fill", attributes: attributes)
Winograd answered 26/4, 2016 at 16:10 Comment(0)
T
2

Now Latest in swift apple remove the [String: Any] for attributes key value declaration use as [NSAttributedStringKey : Any]

    let strokeTextAttributes = [
        NSAttributedStringKey.strokeColor : UIColor.green,
        NSAttributedStringKey.foregroundColor : UIColor.lightGray,
        NSAttributedStringKey.strokeWidth : -4.0,
        NSAttributedStringKey.font : UIFont.boldSystemFont(ofSize: 52)
        ] as [NSAttributedStringKey : Any]

    hello_cell_lb.attributedText = NSAttributedString(string: "\(hello_array[indexPath.row])", attributes: strokeTextAttributes)

thank you

Trapes answered 9/11, 2017 at 12:5 Comment(0)
A
2

Swift 4 version:

let attributes: [NSAttributedStringKey : Any] = [.strokeWidth: -3.0,
                                                 .strokeColor: UIColor.yellow,
                                                 .foregroundColor: UIColor.red]

label.attributedText = NSAttributedString(string: text, attributes: attributes)
Argillaceous answered 11/6, 2018 at 0:17 Comment(0)
R
0

This is an example of Stroke and Oblique/tilt/slant text in UITextView

    public func setAttributedText(fontStyle: INSTextFontPickerStyle, strokeColor: UIColor = UIColor.white, foregroundColor: UIColor = UIColor.black, isObliqueness: Bool = false, isStrokes: Bool = false) {
        self.fontStyle = fontStyle

        let paragraphStyle = NSMutableParagraphStyle()
        paragraphStyle.alignment = innterTextView.textAlignment

        // Tilting the text
        let obliquenessValue = isObliqueness ? NSNumber(value: 0.2) : NSNumber(value: 0) // The angle of tilting in clockwise

        // Stroke a line in text edges
        var strokeWidth = NSNumber(value: 0.0)
        var _strokeColor = UIColor.clear
        if isStrokes || fontStyle == .strokeEdges {
            strokeWidth = NSNumber(value: -2.0) // The width of stroke
            _strokeColor = strokeColor
        }
        
        textView.attributedText = NSAttributedString(string: textView.text, attributes: [
            NSAttributedString.Key.foregroundColor : foregroundColor,
            NSAttributedString.Key.font : UIFont.systemFont(ofSize: (actualFontSize > 0 ? actualFontSize : fontSize)),
            NSAttributedString.Key.paragraphStyle : paragraphStyle,
            NSAttributedString.Key.strokeColor : _strokeColor,
            NSAttributedString.Key.strokeWidth : strokeWidth,
            NSAttributedString.Key.obliqueness: obliquenessValue
        ])
    }
Rubel answered 22/12, 2020 at 12:32 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.