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

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

【问题讨论】:

标签: ios swift cocoa-touch


【解决方案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 即可。漂亮的两行代码。
          • 一旦你把它转换成字符串再转换回属性字符串,它的属性就会消失。
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2023-03-09
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多