Swift NSAttributedString 修剪

Posted

技术标签:

【中文标题】Swift NSAttributedString 修剪【英文标题】:Swift NSAttributedString Trim 【发布时间】:2016-08-03 08:09:02 【问题描述】:

我想摆脱 NSAttributedString 前面和末尾的空白(修剪它)。我不能简单地将其转换为字符串并进行修剪,因为其中有图像(附件)。 我该怎么做?

【问题讨论】:

github.com/ovenbits/Alexandria/blob/master/Sources/… ?如果您在搜索引擎中查找 NSAttributedString 和 Trim,您有一些解决方案,它们不起作用? 谢谢Larme,这个github项目真的很有帮助! 【参考方案1】:

如下创建NSAttributedString 的扩展名。

extension NSAttributedString 
     public func attributedStringByTrimmingCharacterSet(charSet: CharacterSet) -> NSAttributedString 
         let modifiedString = NSMutableAttributedString(attributedString: self)
        modifiedString.trimCharactersInSet(charSet: charSet)
         return NSAttributedString(attributedString: modifiedString)
     


extension NSMutableAttributedString 
     public func trimCharactersInSet(charSet: CharacterSet) 
        var range = (string as NSString).rangeOfCharacter(from: charSet as CharacterSet)

         // Trim leading characters from character set.
         while range.length != 0 && range.location == 0 
            replaceCharacters(in: range, with: "")
            range = (string as NSString).rangeOfCharacter(from: charSet)
         

         // Trim trailing characters from character set.
        range = (string as NSString).rangeOfCharacter(from: charSet, options: .backwards)
         while range.length != 0 && NSMaxRange(range) == length 
            replaceCharacters(in: range, with: "")
            range = (string as NSString).rangeOfCharacter(from: charSet, options: .backwards)
         
     

并在要使用的 viewController 中使用。像这样

let attstring = NSAttributedString(string: "this is test message. Please wait.                   ")
let result = attstring.attributedStringByTrimmingCharacterSet(NSCharacterSet.whitespaceAndNewlineCharacterSet())

【讨论】:

【参考方案2】:

即使在文本中使用表情符号也可以使用

extension NSAttributedString 

    /** Will Trim space and new line from start and end of the text */
    public func trimWhiteSpace() -> NSAttributedString 
        let invertedSet = CharacterSet.whitespacesAndNewlines.inverted
        let startRange = string.utf16.description.rangeOfCharacter(from: invertedSet)
        let endRange = string.utf16.description.rangeOfCharacter(from: invertedSet, options: .backwards)
        guard let startLocation = startRange?.upperBound, let endLocation = endRange?.lowerBound else 
            return NSAttributedString(string: string)
        

        let location = string.utf16.distance(from: string.startIndex, to: startLocation) - 1
        let length = string.utf16.distance(from: startLocation, to: endLocation) + 2
        let range = NSRange(location: location, length: length)
        return attributedSubstring(from: range)
    


用法

let attributeString = NSAttributedString(string: "\n\n\n     Hi ? ?‍?‍??‍?‍?‍??‍?‍?‍??‍?‍??‍??‍?‍?‍??‍?‍?‍??‍?‍?‍??‍?‍??‍?‍??‍?‍??‍? buddy.              ")
let result = attributeString.trimWhiteSpace().string // Hi ? ?‍?‍??‍?‍?‍??‍?‍?‍??‍?‍??‍??‍?‍?‍??‍?‍?‍??‍?‍?‍??‍?‍??‍?‍??‍?‍??‍? buddy.

【讨论】:

嗨,我想从 Nsattributed 字符串中删除最后一个图像附件。你能告诉我我该怎么做吗? @MALIKKHABIBURREHMAN 你的意思是表情符号作为图像吗? 不,图像作为 NSImageAttachment 添加到 NsMutableAttrubtedString。【参考方案3】:

Swift 4 及以上版本

extension NSMutableAttributedString 

    func trimmedAttributedString() -> NSAttributedString 
        let invertedSet = CharacterSet.whitespacesAndNewlines.inverted
        let startRange = string.rangeOfCharacter(from: invertedSet)
        let endRange = string.rangeOfCharacter(from: invertedSet, options: .backwards)
        guard let startLocation = startRange?.upperBound, let endLocation = endRange?.lowerBound else 
            return NSAttributedString(string: string)
        
        let location = string.distance(from: string.startIndex, to: startLocation) - 1
        let length = string.distance(from: startLocation, to: endLocation) + 2
        let range = NSRange(location: location, length: length)
        return attributedSubstring(from: range)
    

使用:

let string = "This is string with some space in the end.     "
let attributedText = NSMutableAttributedString(string: string).trimmedAttributedString()

【讨论】:

【参考方案4】:

我做了一个 swift 3 实现,以防万一有人感兴趣:

/**
 Trim an attributed string. Can for example be used to remove all leading and trailing spaces and line breaks.
 */
public func attributedStringByTrimmingCharactersInSet(set: CharacterSet) -> NSAttributedString 
    let invertedSet = set.inverted
    let rangeFromStart = string.rangeOfCharacter(from: invertedSet)
    let rangeFromEnd = string.rangeOfCharacter(from: invertedSet, options: .backwards)
    if let startLocation = rangeFromStart?.upperBound, let endLocation = rangeFromEnd?.lowerBound 
        let location = string.distance(from: string.startIndex, to: startLocation) - 1
        let length = string.distance(from: startLocation, to: endLocation) + 2
        let newRange = NSRange(location: location, length: length)
        return self.attributedSubstring(from: newRange)
     else 
        return NSAttributedString()
    

【讨论】:

【参考方案5】:

事实证明,Unicode 字符串很难哈哈哈!此处发布的其他解决方案是一个很好的起点,但在使用非拉丁字符串时它们对我来说崩溃了。 每当在 Swift 字符串中使用索引或范围时,我们需要使用 String.Index 而不是普通的 Int。从Range<String.Index> 创建NSRange 必须使用NSRange(swiftRange, in: String)

话虽如此,此代码建立在其他答案的基础上,但使其具有 unicode-proof:

public extension NSMutableAttributedString 

    /// Trims new lines and whitespaces off the beginning and the end of attributed strings
    func trimmedAttributedString() -> NSAttributedString 
        let invertedSet = CharacterSet.whitespacesAndNewlines.inverted
        let startRange = string.rangeOfCharacter(from: invertedSet)
        let endRange = string.rangeOfCharacter(from: invertedSet, options: .backwards)
        guard let startLocation = startRange?.lowerBound, let endLocation = endRange?.lowerBound else 
            return NSAttributedString(string: string)
        

        let trimmedRange = startLocation...endLocation
        return attributedSubstring(from: NSRange(trimmedRange, in: string))
    

【讨论】:

喜欢这种方法。对于没有任何非空白字符的情况,它可能应该返回一个空的属性字符串。【参考方案6】:

Swift 3.2 版本:

extension NSAttributedString 
    public func trimmingCharacters(in characterSet: CharacterSet) -> NSAttributedString 
        let modifiedString = NSMutableAttributedString(attributedString: self)
        modifiedString.trimCharacters(in: characterSet)
        return NSAttributedString(attributedString: modifiedString)
    


extension NSMutableAttributedString 
    public func trimCharacters(in characterSet: CharacterSet) 
        var range = (string as NSString).rangeOfCharacter(from: characterSet)

        // Trim leading characters from character set.
        while range.length != 0 && range.location == 0 
            replaceCharacters(in: range, with: "")
            range = (string as NSString).rangeOfCharacter(from: characterSet)
        

        // Trim trailing characters from character set.
        range = (string as NSString).rangeOfCharacter(from: characterSet, options: .backwards)
        while range.length != 0 && NSMaxRange(range) == length 
            replaceCharacters(in: range, with: "")
            range = (string as NSString).rangeOfCharacter(from: characterSet, options: .backwards)
        
    

【讨论】:

【参考方案7】:

以下代码将满足您的要求。

var attString: NSAttributedString = NSAttributedString(string: " this is att string")

let trimmedString = attString.string.stringByTrimmingCharactersInSet(NSCharacterSet.whitespaceCharacterSet())

【讨论】:

我究竟如何获得范围? 尝试上面提到的代码,从属性字符串中删除前后空格。 以上代码工作正常。但它会返回String 而不是NSAttributedString。您只需将String 转换为NSAttributedString 即可。漂亮的两行代码。 一旦你把它转换成字符串再转换回属性字符串,它的属性就会消失。

以上是关于Swift NSAttributedString 修剪的主要内容,如果未能解决你的问题,请参考以下文章

NSAttributedString in Swift

Swift NSAttributedString 修剪

Swift - 带有链接的 HTML 风格化 NSAttributedString

Swift 4 - 如何在核心数据中保存 NSAttributedstring

显示带有不间断空格和多行的 NSAttributedString 的 Swift 错误

使用 Swift 在 iOS 11 中为 NSAttributedString 添加删除线