枚举可变属性字符串(下划线按钮) [英] Enumerate over a Mutable Attributed String (Underline Button)

查看:91
本文介绍了枚举可变属性字符串(下划线按钮)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试创建一个 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆