0

Since iOS 16, TextKit 2 has replaced TextKit 1 for UITextView which means layoutManager is out and textLayoutManager is in. However, a number of the properties from the old are not in the new. How can I calculate the number of lines in a UITextView using TextKit 2? Below is the TextKit 1 implementation.

extension UITextView {
    var numberOfLines: Int {
        if #available(iOS 16.0, *) {
            // TextKit 2

            let layout = textLayoutManager // new layout manager
        } else {
            // TextKit 1

            let layout = layoutManager // old layout manager
            var lines = 0
            var index = 0
            var lineRange = NSRange()
            
            while index < layout.numberOfGlyphs {
                layout.lineFragmentRect(forGlyphAt: index, effectiveRange: &lineRange)
                index = NSMaxRange(lineRange)
                lines += 1
            }
            return max(1, lines)
        }
    }
}
lurning too koad
  • 2,698
  • 1
  • 17
  • 47
  • NSTextLayoutManager seems there is no options to access properties to calculate number of lines from UITextView. But Why you don't try this simple process for getting number of lines from UITextView ? https://stackoverflow.com/a/36626498/3683408 – Ram Mar 04 '23 at 10:24
  • @Ram dividing the content height by the font's line height doesn't work on the keystroke that breaks the line, only the following keystroke. The code in my answer is bulletproof for all edge cases (keystroke, autocomplete, paste). I just want to find the TextKit 2 variant. – lurning too koad Mar 04 '23 at 17:55

1 Answers1

0

You can use enumerateTextLayoutFragments to get the 'real' number of lines, which are divided by '\n'.

var count = 0
textView.textLayoutManager?.enumerateTextLayoutFragments(from: textView.textLayoutManager?.documentRange.location,
                                                         options: [.ensuresLayout, .ensuresExtraLineFragment],
                                                         using: { _ in
    count += 1
    return true // keep going
})
Chocoford
  • 183
  • 8