枚举可变属性字符串(下划线按钮) [英] Enumerate over a Mutable Attributed String (Underline Button)
问题描述
我正在尝试创建一个 UIButton
允许为所选文本加下划线.这是我当前的代码:
I am trying to create a UIButton
that allows the selected text to be underlined. This is my current code:
func underline() {
if let textRange = selectedRange {
let attributedString = NSMutableAttributedString(attributedString: textView.attributedText)
textView.textStorage.addAttributes([.underlineStyle : NSUnderlineStyle.single.rawValue], range: textRange)
}
}
它目前正在加下划线,但我遇到的问题是我需要检查当前文本是否已经加下划线以及是否删除了下划线.我似乎无法用 NSMutableAttributedString
解决这个问题.
It is currently underlining but the problem I am having is that I need to check if the current text is underlined already and if it is remove the underline. I can't seem to work this out with the NSMutableAttributedString
.
我使用斜体 UIButton
这样做:
I am doing this with an Italic UIButton
like so:
func italic() {
if let textRange = selectedRange {
let attributedString = NSAttributedString(attributedString: textView.attributedText)
attributedString.enumerateAttribute(.font, in: textRange, options: []) { (font, range, pointee) in
let newFont: UIFont
if let font = font as? UIFont {
let fontTraits = font.fontDescriptor.symbolicTraits
if fontTraits.contains(.traitItalic) {
newFont = UIFont.systemFont(ofSize: font.pointSize, weight: .regular)
} else {
newFont = UIFont.systemFont(ofSize: font.pointSize).italic()
}
textView.textStorage.addAttributes([.font : newFont], range: textRange)
}
}
}
}
如何实现检查当前文本是否具有第一个函数的下划线属性的能力?
How can I achieve the ability to check if the current text has the underlining attribute for my first function?
我们目前的代码:
func isUnderlined(attrText: NSAttributedString) -> Bool {
var contains: ObjCBool = false
attrText.enumerateAttributes(in: NSRange(location: 0, length: attrText.length), options: []) { (dict, range, value) in
if dict.keys.contains(.underlineStyle) {
contains = true
}
}
return contains.boolValue
}
func underline() {
if let textRange = selectedRange {
let attributedString = NSMutableAttributedString(attributedString: textView.attributedText)
switch self.isUnderlined(attrText: attributedString) {
case true:
print("true")
textView.textStorage.removeAttribute(.underlineStyle, range: textRange)
case false:
print("remove")
textView.textStorage.addAttributes([.underlineStyle : NSUnderlineStyle.single.rawValue], range: textRange)
}
}
}
推荐答案
要检查文本是否已经加下划线,您可以简单地运行 contains(_:)
on文本的属性,即
To check if a text is already underlined, you can simply run contains(_:)
on the attributes of the text, i.e.
func isUnderlined(attrText: NSAttributedString) -> Bool {
var contains: ObjCBool = false
attrText.enumerateAttributes(in: NSRange(location: 0, length: attrText.length), options: []) { (dict, range, value) in
if dict.keys.contains(.underlineStyle) {
contains = true
}
}
return contains.boolValue
}
示例:
let attrText1 = NSAttributedString(string: "This is an underlined text.", attributes: [.underlineStyle : NSUnderlineStyle.styleSingle.rawValue])
let attrText2 = NSAttributedString(string: "This is an underlined text.", attributes: [.font : UIFont.systemFontSize])
print(self.isUnderlined(attrText: attrText1)) //true
print(self.isUnderlined(attrText: attrText2)) //false
您可以根据需要在 UITextView
中使用上述逻辑.
You can use the above logic in your UITextView
as per your requirement.
要删除属性,
1.首先它必须是一个NSMutableAttributedString
.
2. 然后要删除一个属性,在属性字符串上使用 removeAttribute(_:range:)
方法.
2. Then to remove an attribute, use removeAttribute(_:range:)
method on attributed string.
let attrText1 = NSMutableAttributedString(string: "This is an underlined text.", attributes: [.underlineStyle : NSUnderlineStyle.styleSingle.rawValue])
print(self.isUnderlined(attrText: attrText1)) //true
if self.isUnderlined(attrText: attrText1) {
attrText1.removeAttribute(.underlineStyle, range: NSRange(location: 0, length: attrText1.string.count))
}
print(self.isUnderlined(attrText: attrText1)) //false
在按钮点击时处理 textView
@IBAction func onTapButton(_ sender: UIButton) {
if let selectedTextRange = self.textView.selectedTextRange {
let location = self.textView.offset(from: textView.beginningOfDocument, to: selectedTextRange.start)
let length = self.textView.offset(from: selectedTextRange.start, to: selectedTextRange.end)
let range = NSRange(location: location, length: length)
self.textView.attributedText.enumerateAttributes(in: range, options: []) { (dict, range, value) in
if dict.keys.contains(.underlineStyle) {
self.textView.textStorage.removeAttribute(.underlineStyle, range: range)
} else {
self.textView.textStorage.addAttributes([.underlineStyle : NSUnderlineStyle.styleSingle.rawValue], range: range)
}
}
}
}
这篇关于枚举可变属性字符串(下划线按钮)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!