Skip to content

Instantly share code, notes, and snippets.

@alexpersian
Last active August 21, 2023 03:22
Show Gist options
  • Star 9 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save alexpersian/c63965421df7994929c11bf60bb9af27 to your computer and use it in GitHub Desktop.
Save alexpersian/c63965421df7994929c11bf60bb9af27 to your computer and use it in GitHub Desktop.
Extension on UITextView that allows for the detection of truncation.
extension UITextView {
// Massive credit to Dave Delong for his extensive help with this solution.
/// Returns whether or not the `UITextView` is displaying truncated text. This includes text
/// that is visually truncated with an ellipsis (...), and text that is simply cut off through
/// word wrapping.
///
/// - Important:
/// This only works properly when the `NSLineBreakMode` is set to `.byTruncatingTail` or `.byWordWrapping`.
///
/// - Remark:
/// Calculation enumerates over all line fragments that the textview's LayoutManger generates
/// and checks for the presence of the truncation glyph. If the textview's `NSLineBreakMode` is
/// not set to `.byTruncatingTail` this calculation will be based on whether the textview's
/// character content extends beyond its view frame.
var isTextTruncated: Bool {
var isTruncating = false
// The `truncatedGlyphRange(...) method will tell us if text has been truncated
// based on the line break mode of the text container
layoutManager.enumerateLineFragments(forGlyphRange: NSRange(location: 0, length: Int.max)) { _, _, _, glyphRange, stop in
let truncatedRange = self.layoutManager.truncatedGlyphRange(inLineFragmentForGlyphAt: glyphRange.lowerBound)
if truncatedRange.location != NSNotFound {
isTruncating = true
stop.pointee = true
}
}
// It's possible that the text is truncated not because of the line break mode,
// but because the text is outside the drawable bounds
if isTruncating == false {
let glyphRange = layoutManager.glyphRange(for: textContainer)
let characterRange = layoutManager.characterRange(forGlyphRange: glyphRange, actualGlyphRange: nil)
isTruncating = characterRange.upperBound < text.utf16.count
}
return isTruncating
}
}
@nilsnilsnils
Copy link

nilsnilsnils commented Jul 26, 2022

Hi.

First. Thanks for your hard work.

It helped me a lot but for me and my coder under iOS 15.2 the truncatedGlyphRange method doesn't return the range of the truncated glyph. E.g. when I use a word like "Mmmmmm...(m repeating)".

So my UITextView doesn't show the last m but the function doesn't tell me that the text is truncated.
lineBreakMode is .byWordWrapping and scrolling disabled maximumNumberOfLines = 0

Maybe some weird behavior in my code ?

@worldbridgerstudios
Copy link

Works perfectly, thank you sincerely.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment