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 修剪的主要内容,如果未能解决你的问题,请参考以下文章
Swift - 带有链接的 HTML 风格化 NSAttributedString
Swift 4 - 如何在核心数据中保存 NSAttributedstring