While add Stroke to UILabel App Crashes
It Crash due to found nil
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)
You seem to add stroke to a nil label in cell but it works here
I have a UIButton, on which I set a UIImage (by using set(_:for:) method). After that, I add a label on it with some text (It should be white). The problem is: When I use some photos, which have bright colours (close to white), it's hard to see some characters of the text. Here how it looks like (the button isn't very big, hence the quality of the image is low, too):
I've tried to add a UIView between the button and the label and to manipulate its alpha, but that doesn't help. If you know how the problem can be solved (without changing text's colour), I would appreciate your help.
The most common approach is to set the label's background color to a partially transparent black color. Then maybe round the labels corners for a nice look.
let label = ... // your label
label.backgroundColor = UIColor(white: 0.0, alpha: 0.4) // adjust alpha as desired
label.layer.cornerRadius = 4 // adjust as desired
Another option, instead of adding a background to the label, is to use attribute text for the label and give the white text a black outline.
let attrs: [NSAttributedStringKey: Any] = [
.foregroundColor: UIColor.white,
.strokeColor: UIColor.black,
.strokeWidth: -2.0,
.font: UIFont.systemFont(ofSize: 20) // Use whatever font you want
]
let attrStr = NSAttributedString(string: "Grand Royal", attributes: attrs)
label.attributedText = attrStr
Yet another option is to setup the label with a shadow:
let label = ... // your label
label.shadowColor = .black
label.shadowSize = CGSize(width: 1, height: 1)
The shadow can be created using attribute text and this gives you more control:
let shadow = NSShadow()
shadow.shadowColor = UIColor.black
shadow.shadowOffset = CGSize(width: 0, height: 0)
shadow.shadowBlurRadius = 3
let attrs: [NSAttributedStringKey: Any] = [
.foregroundColor: UIColor.white,
.shadow: shadow,
.font: UIFont.systemFont(ofSize: 40)
]
let attrStr = NSAttributedString(string: "Grand Royal", attributes: attrs)
label.attributedText = attrStr
This puts a halo around the text. Adjust the shadow properties to suit your needs.
Dears,
I'm learning swift and I'm trying to color a textfield text, the issue now is that the color is not applied to the text. please find the code next:
let textStyle:[String:Any] = [
NSAttributedStringKey.strokeColor.rawValue: UIColor.black,
NSAttributedStringKey.foregroundColor.rawValue: UIColor.white,
NSAttributedStringKey.font.rawValue: UIFont (name: "Impact", size: 50)!,
NSAttributedStringKey.strokeWidth.rawValue: 3.5
]
Thanks
The key appears to be the .strokeWidth... If you want stroke and fill, the stroke width needs to be a negative value.
Give this a try:
let textStyle = [
NSAttributedStringKey.strokeColor: UIColor.black,
NSAttributedStringKey.foregroundColor: UIColor.white,
NSAttributedStringKey.font: UIFont(name: "Impact", size: 50)!,
NSAttributedStringKey.strokeWidth: -3.5
]
can you try this...
myTextField.attributedText = NSAttributedString(string: "text",
attributes: [NSAttributedStringKey.foregroundColor: UIColor.white])
I'm trying hard to find a way to simply add an outline/stroke/contour to my UILabel text. Talking about a stroke around the letters of the text not around the background of a UILabel.
I'm using swift 3 and I'd like to outline my text directly into my subclass: UILabel.
I found multiple answers suggesting this way to do things :
let strokeTextAttributes = [
NSStrokeColorAttributeName : UIColor.black,
NSForegroundColorAttributeName : UIColor.white,
NSStrokeWidthAttributeName : -4.0,
NSFontAttributeName : UIFont.boldSystemFont(ofSize: 30)
]
self.attributedText = NSMutableAttributedString(string: self.text!, attributes: strokeTextAttributes)
But the thing is that it doesn't work. My text is still the same with no outline...
Could anyone help me here ?
That would be a great thing :)
Thanks a lot. Cheers guys.
This code works for me.
Swift 3
let strokeTextAttributes = [
NSStrokeColorAttributeName : UIColor.black,
NSForegroundColorAttributeName : UIColor.white,
NSStrokeWidthAttributeName : -4.0,
NSFontAttributeName : UIFont.boldSystemFont(ofSize: 30)
] as [String : Any]
myLabel.attributedText = NSMutableAttributedString(string: "Test me i have color.", attributes: strokeTextAttributes)
Swift 4.2 & 5.1
let strokeTextAttributes = [
NSAttributedString.Key.strokeColor : UIColor.red,
NSAttributedString.Key.foregroundColor : UIColor.white,
NSAttributedString.Key.strokeWidth : -4.0,
NSAttributedString.Key.font : UIFont.boldSystemFont(ofSize: 30)]
as [NSAttributedString.Key : Any]
labelOutLine.attributedText = NSMutableAttributedString(string: "Your outline text", attributes: strokeTextAttributes)
#anandnimje answer converted to Swift 4.2 and wrapped it into a function:
public func stroke(font: UIFont, strokeWidth: Float, insideColor: UIColor, strokeColor: UIColor) -> [NSAttributedStringKey: Any]{
return [
NSAttributedStringKey.strokeColor : strokeColor,
NSAttributedStringKey.foregroundColor : insideColor,
NSAttributedStringKey.strokeWidth : -strokeWidth,
NSAttributedStringKey.font : font
]
}
Usage:
label.attributedText = NSMutableAttributedString(string: "Hello World",
attributes: stroke(font: UIFont(name: "SourceSansPro-Black", size: 20)!,
strokeWidth: 4, insideColor: .white, strokeColor: .black))
Make sure you have the right name for your UIFont, else it crashes. Should never be a problem if you have the right name.
Here you have class with implementation, copy and paste to playgrond for test:
class StrokedLabel: UILabel {
var strockedText: String = "" {
willSet(newValue) {
let strokeTextAttributes = [
NSStrokeColorAttributeName : UIColor.black,
NSForegroundColorAttributeName : UIColor.white,
NSStrokeWidthAttributeName : -4.0,
NSFontAttributeName : UIFont.boldSystemFont(ofSize: 30)
] as [String : Any]
let customizedText = NSMutableAttributedString(string: newValue,
attributes: strokeTextAttributes)
attributedText = customizedText
}
}
}
//////////// PLAYGROUND IMPLEMENTATION PART /////////
let text = "Stroked text"
// UILabel subclass initialization
let label = StrokedLabel(frame: CGRect(x: 0, y: 0, width: 200, height: 50))
// simple assign String to 'strockedText' property to see the results
label.strockedText = text
label.backgroundColor = UIColor.white
label
Swift 4.2
import UIKit
class StrokedLabel: UILabel {
var strockedText: String = "" {
willSet(newValue) {
let strokeTextAttributes : [NSAttributedString.Key : Any] = [
NSAttributedString.Key.strokeColor : UIColor.black,
NSAttributedString.Key.foregroundColor : UIColor.white,
NSAttributedString.Key.strokeWidth : -4.0,
NSAttributedString.Key.font : UIFont.boldSystemFont(ofSize: 30)
] as [NSAttributedString.Key : Any]
let customizedText = NSMutableAttributedString(string: newValue,
attributes: strokeTextAttributes)
attributedText = customizedText
}
}
}
//////////// PLAYGROUND IMPLEMENTATION PART /////////
let text = "Stroked text"
// UILabel subclass initialization
let label = StrokedLabel(frame: CGRect(x: 0, y: 0, width: 200, height: 50))
// simple assign String to 'strockedText' property to see the results
label.strockedText = text
label.backgroundColor = UIColor.clear
label
Maybe refactoring for this class will be welcomed, but should work for you at this form
As you can see usage is very convenient. 👾
Update to Swift 5
This answer is built on Anandnimje and J.Doe answers, and is meant to update and streamline it to make the usage clearer and simpler.
Simply use these two functions:
func outline(string:String, font:String, size:CGFloat, outlineSize:Float, textColor:UIColor, outlineColor:UIColor) -> NSMutableAttributedString {
return NSMutableAttributedString(string:string,
attributes: outlineAttributes(font: UIFont(name: font, size: size)!,
outlineSize: outlineSize, textColor: textColor, outlineColor: outlineColor))
}
func outlineAttributes(font: UIFont, outlineSize: Float, textColor: UIColor, outlineColor: UIColor) -> [NSAttributedString.Key: Any]{
return [
NSAttributedString.Key.strokeColor : outlineColor,
NSAttributedString.Key.foregroundColor : textColor,
NSAttributedString.Key.strokeWidth : -outlineSize,
NSAttributedString.Key.font : font
]
}
Then use outline with your labels as the following:
label.attributedText = outline(string: "Label Text", font: "HelveticaNeue", size: 14, outlineSize: 4, textColor: .white, outlineColor: .black)
Below is what I used in my App written in Swift 4.1
Swift 4.x
let strokeTextAttributes: [NSAttributedStringKey: Any] = [
NSAttributedStringKey.strokeColor: UIColor.black,
NSAttributedStringKey.foregroundColor : UIColor.white,
NSAttributedStringKey.strokeWidth : -3.0,
NSAttributedStringKey.font : UIFont.boldSystemFont(ofSize: 18)
]
Your code works for me if I set the type of the attributes dictionary, like this:
let strokeTextAttributes: [String: Any] = [
// etc...
]
Maybe that's all your missing?
I am trying to make the fill for this text white, but the fill is transparent, and when I change the NSForegroundAttribureName, it has no effect below is my code.
let textAttributes = [
NSFontAttributeName : UIFont(name: "HelveticaNeue-CondensedBlack", size: 40)!,
NSStrokeWidthAttributeName : 3.0,
NSForegroundColorAttributeName : UIColor.whiteColor(),
NSStrokeColorAttributeName : UIColor.blackColor()
]
In viewDidLoad()
textFieldTop.defaultTextAttributes = textAttributes
How do I make the fill for the font white?
let textAttributes = [
NSFontAttributeName : UIFont(name: "HelveticaNeue-CondensedBlack", size: 40)!,
NSStrokeWidthAttributeName : -3.0,//Shpuld be in minus
NSForegroundColorAttributeName : UIColor.whiteColor(),
NSStrokeColorAttributeName : UIColor.blackColor()
]
Text becomes invisible when stroke is added
kCTStrokeWidthAttributeName. This attribute, interpreted as a percentage of font point size, controls the text drawing mode: positive values effect drawing with stroke only; negative values are for stroke and fill.