2017-01-13 14 views
1

には、一部の属性付きテキストがあります。textContainer.maximumNumberOfLineが設定されています(この場合は3)。UITextView:切り捨てられたテキスト内の省略記号の位置を確認します。

属性文字列の文字範囲内の省略記号のインデックスを探したいとします。

例えば:

元の文字列:

"Lorem ipsum dolor sit amet, consectetur adipiscing elit"

文字列切り捨てた後、表示される:

Lorem ipsum dolor sit amet, consectetur...

私は...のインデックスを決定するにはどうすればよいですか?

答えて

2

ここには、ジョブを実行する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 
} 

として注意をそれを投稿しようと思いましたいくつかの単純なケースを超えてテストされています。いくつかの調整が必要なエッジケースがあるかもしれません。

+0

非常に良いアプローチ – greenisus

関連する問題