ここには、ジョブを実行するNSAttributedStringの拡張機能があります。単一の&複数行テキストのための作品。
これは把握する私に約8時間のすべてを取ったので、私は、私はこれがない持っていることをQ & A.
(スウィフト2.2)
/**
Returns the index of the ellipsis, if this attributed string is truncated, or NSNotFound otherwise.
*/
func truncationIndex(maximumNumberOfLines: Int, width: CGFloat) -> Int {
//Create a dummy text container, used for measuring & laying out the text..
let textContainer = NSTextContainer(size: CGSize(width: width, height: CGFloat.max))
textContainer.maximumNumberOfLines = maximumNumberOfLines
textContainer.lineBreakMode = NSLineBreakMode.ByTruncatingTail
let layoutManager = NSLayoutManager()
layoutManager.addTextContainer(textContainer)
let textStorage = NSTextStorage(attributedString: self)
textStorage.addLayoutManager(layoutManager)
//Determine the range of all Glpyhs within the string
var glyphRange = NSRange()
layoutManager.glyphRangeForCharacterRange(NSMakeRange(0, self.length), actualCharacterRange: &glyphRange)
var truncationIndex = NSNotFound
//Iterate over each 'line fragment' (each line as it's presented, according to your `textContainer.lineBreakMode`)
var i = 0
layoutManager.enumerateLineFragmentsForGlyphRange(glyphRange) { (rect, usedRect, textContainer, glyphRange, stop) in
if (i == maximumNumberOfLines - 1) {
//We're now looking at the last visible line (the one at which text will be truncated)
let lineFragmentTruncatedGlyphIndex = glyphRange.location
if lineFragmentTruncatedGlyphIndex != NSNotFound {
truncationIndex = layoutManager.truncatedGlyphRangeInLineFragmentForGlyphAtIndex(lineFragmentTruncatedGlyphIndex).location
}
stop.memory = true
}
i += 1
}
return truncationIndex
}
として注意をそれを投稿しようと思いましたいくつかの単純なケースを超えてテストされています。いくつかの調整が必要なエッジケースがあるかもしれません。
非常に良いアプローチ – greenisus