可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I'm moving from swift 3 to swift 4. I have UILabels that I am giving very specific text properties to the label. I'm getting an 'unexpectedly found nil while unwrapping optional value' error when strokeTextAttributes is being initialized. I'm totally lost to be frank.
In swift 3 the of strokeTextAttributes was [String : Any] but swift 4 threw errors until I changed it to what it is below.
let strokeTextAttributes = [
NSAttributedStringKey.strokeColor.rawValue : UIColor.black,
NSAttributedStringKey.foregroundColor : UIColor.white,
NSAttributedStringKey.strokeWidth : -2.0,
NSAttributedStringKey.font : UIFont.boldSystemFont(ofSize: 18)
] as! [NSAttributedStringKey : Any]
chevronRightLabel.attributedText = NSMutableAttributedString(string: "0", attributes: strokeTextAttributes)
回答1:
@Larme's comment about the .rawValue
not being needed is correct.
Also, you can avoid the force cast that crashes your code using explicit typing:
let strokeTextAttributes: [NSAttributedString.Key: Any] = [
.strokeColor : UIColor.black,
.foregroundColor : UIColor.white,
.strokeWidth : -2.0,
.font : UIFont.boldSystemFont(ofSize: 18)
]
This gets rid of the repetitive NSAttributedString.Key.
, too.
回答2:
In Swift 4.0+
, attributed string accepts json (dictionary) with key type NSAttributedStringKey
or NSAttributedString.Key
.
So you must change it from [String : Any]
to
Swift 4.1 & below - [NSAttributedStringKey : Any]
&
Swift 4.2 & above - [NSAttributedString.Key : Any]
Swift 4.2
Initialiser for AttributedString
in Swift 4.2 is changed to [NSAttributedString.Key : Any]?
public init(string str: String, attributes attrs: [NSAttributedString.Key : Any]? = nil)
Here is sample working code.
let label = UILabel()
let labelText = "String Text"
let strokeTextAttributes = [
NSAttributedString.Key.strokeColor : UIColor.black,
NSAttributedString.Key.foregroundColor : UIColor.white,
NSAttributedString.Key.strokeWidth : -2.0,
NSAttributedString.Key.font : UIFont.boldSystemFont(ofSize: 18)
] as [NSAttributedString.Key : Any]
label.attributedText = NSAttributedString(string: labelText, attributes: strokeTextAttributes)
Swift 4.0
Initialiser for AttributedString
in Swift 4.0 is changed to [NSAttributedStringKey : Any]?
.
public init(string str: String, attributes attrs: [NSAttributedStringKey : Any]? = nil)
Here is sample working code.
let label = UILabel()
let labelText = "String Text"
let strokeTextAttributes = [
NSAttributedStringKey.strokeColor : UIColor.black,
NSAttributedStringKey.foregroundColor : UIColor.white,
NSAttributedStringKey.strokeWidth : -2.0,
NSAttributedStringKey.font : UIFont.boldSystemFont(ofSize: 18)
] as [NSAttributedStringKey : Any]
label.attributedText = NSAttributedString(string: labelText, attributes: strokeTextAttributes)
Look at this Apple Document, for more info: NSAttributedString - Creating an NSAttributedString Object
回答3:
NSAttributedStringKey.strokeColor.rawValue
is of type String
NSAttributedStringKey.strokeColor
is of type NSAttributedStringKey
So its unable to convert String
to NSAttributedStringKey
.
You have to use like below:
let strokeTextAttributes: [NSAttributedStringKey : Any] = [
NSAttributedStringKey.strokeColor : UIColor.black,
NSAttributedStringKey.foregroundColor : UIColor.white,
NSAttributedStringKey.strokeWidth : -2.0,
NSAttributedStringKey.font : UIFont.boldSystemFont(ofSize: 18)
]
回答4:
Swift 4 Attributed text with multiple colors
extension NSMutableAttributedString
{
@discardableResult func DustyOrange(_ text: String, Fontsize : CGFloat) -> NSMutableAttributedString
{
let attrs: [NSAttributedStringKey: Any] = [.font: UIFont(name: "SFUIDisplay-Regular", size: Fontsize)!, NSAttributedStringKey.foregroundColor: UIColor(red: 242.0/255.0, green: 97.0/255.0, blue: 0.0/255.0, alpha: 1.0) ]
let boldString = NSMutableAttributedString(string:text, attributes: attrs)
append(boldString)
return self
}
@discardableResult func WarmGrey(_ text: String, Fontsize : CGFloat) -> NSMutableAttributedString {
let attrs: [NSAttributedStringKey: Any] = [.font: UIFont(name: "SFUIDisplay-Regular", size: Fontsize)!, NSAttributedStringKey.foregroundColor: UIColor(red: 152.0/255.0, green: 152.0/255.0, blue: 152.0/255.0, alpha: 1.0) ]
let boldString = NSMutableAttributedString(string:text, attributes: attrs)
append(boldString)
return self
}
}
Now you can Execute the function something like this to use as a globally
func FormattedString(Orange : String, WarmGrey : String ,fontsize : CGFloat) -> NSMutableAttributedString
{
let paragraphStyle = NSMutableParagraphStyle()
paragraphStyle.alignment = .left
paragraphStyle.lineSpacing = 1
paragraphStyle.paragraphSpacing = 1
let formattedString = NSMutableAttributedString()
formattedString
.DustyOrange(Orange, Fontsize: fontsize)
.WarmGrey(WarmGrey, Fontsize: fontsize )
formattedString.addAttributes([NSAttributedStringKey.paragraphStyle: paragraphStyle], range: NSRange(location: 0, length: formattedString.length))
return formattedString
}
You can use globalized function like this
yourLabelName.attributedText = FormattedString(Orange: "String with orange color", WarmGrey: " String with warm grey color.", fontsize: 11.5)
Attributed text with image
func AttributedTextwithImgaeSuffix(AttributeImage : UIImage , AttributedText : String , buttonBound : UIButton) -> NSMutableAttributedString
{
let fullString = NSMutableAttributedString(string: AttributedText + " ")
let image1Attachment = NSTextAttachment()
image1Attachment.bounds = CGRect(x: 0, y: ((buttonBound.titleLabel?.font.capHeight)! -
AttributeImage.size.height).rounded() / 2, width:
AttributeImage.size.width, height: AttributeImage.size.height)
image1Attachment.image = AttributeImage
let image1String = NSAttributedString(attachment: image1Attachment)
fullString.append(image1String)
fullString.append(NSAttributedString(string: ""))
return fullString
}
you can use "NSTextAttachment" with your button label like this.
yourUIButton.setAttributedTitle(AttributedTextwithImgaeSuffix(AttributeImage: desiredImage, AttributedText: "desired UIButton title", buttonBound: yourUIButton), for: .normal)
回答5:
In Swift 4.x, this should look like :
let strokeTextAttributes: [NSAttributedStringKey: Any] = [
NSStrokeColorAttributeName: UIColor.black,
NSForegroundColorAttributeName : UIColor.white,
NSStrokeWidthAttributeName : -2.0,
NSFontAttributeName : UIFont.boldSystemFont(ofSize: 18)
]
回答6:
if you want to change particular string value so that below answer is helpful you:-
let subStr = "Hello"
let allStr = "Hello World"
let newStr = NSMutableAttributedString(string: allStr)
newStr.addAttribute(kCTFontAttributeName as NSAttributedStringKey, value: UIFont.init(customFont: .MyriadPro_R, withSize: 18)!, range: (allStr as NSString).range(of: subStr))
newStr.addAttribute(NSAttributedStringKey.foregroundColor, value: UIColor.PrimaryColor, range: (allStr as NSString).range(of: subStr))
self.stateLbl.attributedText = newStr
回答7:
let text = systolicString + " / " + diastolicString
let newStr = NSMutableAttributedString(string: text)
// I have static ranges, but you can also extract them dynamically
let systolicRange = NSRange(location: 0, length: 2)
let backslashRange = NSRange(location: 3, length: 1)
let diastolicRange = NSRange(location: 5, length: 2)
newStr.addAttribute(NSAttributedStringKey.font, value: UIFont.ubuntuRegular(28), range: systolicRange)
newStr.addAttribute(NSAttributedStringKey.foregroundColor, value: UIColor(hexString: "042f57"), range: systolicRange)
newStr.addAttribute(NSAttributedStringKey.font, value: UIFont.ubuntuLight(23), range: backslashRange)
newStr.addAttribute(NSAttributedStringKey.foregroundColor, value: UIColor(hexString: "6485a3"), range: backslashRange)
newStr.addAttribute(NSAttributedStringKey.font, value: UIFont.ubuntuRegular(18), range: diastolicRange)
newStr.addAttribute(NSAttributedStringKey.foregroundColor, value: UIColor(hexString: "042f57"), range: diastolicRange)
// my UILabel
valueLabel.attributedText = newStr