[Tips] UITextView의 행 수 등을 가져옵니다.



개요



UITextview의 표시 상태 취득을 위한 Tips. 덧붙여서 설정계는 [Tips] UITextview를 UILabel처럼 사용 로.

0, 취득 타이밍에 대해



같은 text에서도 표시 영역이 다르면 행수도 바뀌어 오는 것으로, 예를 들면 표시 전에 정보를 취득하려고 생각해도 잘 되지 않는 경우가 많다. AutoLayout이 기반이라면 UIViewController 라이프 사이클 viewWillLayoutSubViews 타이밍에서 얻는 것이 좋습니다.

1, 행수를 취득한다



UITextView의 행 수 얻기
extension UITextView {
    var numberOfLines: Int {
        // prepare
        var computingLineIndex = 0
        var computingGlyphIndex = 0
        // compute
        while computingGlyphIndex < layoutManager.numberOfGlyphs {
            var lineRange = NSRange()
            layoutManager.lineFragmentRect(forGlyphAt: computingGlyphIndex, effectiveRange: &lineRange)
            computingGlyphIndex = NSMaxRange(lineRange)
            computingLineIndex += 1
        }
        // return
        if textContainer.maximumNumberOfLines > 0 {
            return min(textContainer.maximumNumberOfLines, computingLineIndex)
        } else {
            return computingLineIndex
        }
    }
}

Apple 공식 문서에 방법(Objective-C!!!)이 나와 있었으므로 이것을 참고로 구현. 다만, 솔직하게 실장해 보면, 「최대 행수 설정하고 있는데 개행의 들어가는 방법에 따라서는 그것보다 큰 수가 돌려 버린다」라고 하는 불편이 있었기 때문에, 상기와 같이 반환값에 조금 궁리를 했다.

참고 : Apple: Text Layout Programming Guide: Counting Lines of Text

2, 표시 생략되어 있는지를 취득한다



UITextView 표시 생략 되었습니까?
extension UITextView {
    var isTruncated: Bool {
        // prepare
        let lineMax = textContainer.maximumNumberOfLines > 0 ? textContainer.maximumNumberOfLines : Int.max
        var computingLineIndex = 0
        var computingGlyphIndex = 0
        // compute & return
        while computingGlyphIndex < layoutManager.numberOfGlyphs {
            // analyze line
            let overLineMax = computingLineIndex > lineMax
            let existsTruncatedGlyph: Bool = {
                let truncatedGlyphRange = layoutManager.truncatedGlyphRange(inLineFragmentForGlyphAt: computingGlyphIndex)
                return truncatedGlyphRange.location != NSNotFound
            }()
            // guard
            guard !overLineMax, !existsTruncatedGlyph else {
                return true
            }
            // prepare for next
            var lineRange = NSRange()
            self.layoutManager.lineFragmentRect(forGlyphAt: computingGlyphIndex, effectiveRange: &lineRange)
            computingGlyphIndex = NSMaxRange(lineRange)
            computingLineIndex += 1
        }
        return false
    }
}

1의 응용. 지정된 행의 생략 문자 위치를 취득하는 함수 truncatedGlyphRange(inLineFragmentForGlyphAt:)가 layoutManager에 있기 (위해)때문에 이것을 사용한다.

덧붙여서, 설정계의 이야기이지만, .textContainer.lineBreakMode = .byTruncatingTail 라든지의 설정을 하지 않으면 3점 리더등의 생략 문자는 나오지 않는다.

비고



(특히 없음)

좋은 웹페이지 즐겨찾기