0

I have a UITextView set to preview 4 lines of text, when the user clicks 'read more', the limit is set to 0 max lines and it displays at full length.

func showMore() {
    self.readMoreLabel.snp.updateConstraints { (make) -> Void in
        make.height.equalTo(0)
    }

    _descriptionHeight?.deactivate()
    descriptionTextView.textContainer.maximumNumberOfLines = 0
    descriptionTextView.invalidateIntrinsicContentSize()
}

This works fine, but in some instances there are less than or equal to 4 lines of text, so there is no need for a 'read more' button.

I cant see any way to calculate if the text is less than the 4 line limit to hide the read more button. As the content size is forced by the line limit so i cant check that vs the frame height or similar standard methods.

Here is what i tried with no luck:

func setDescription(_ description: NSAttributedString) {
    descriptionTextView.attributedText = description

    setNeedsLayout()
    layoutIfNeeded()

    if descriptionTextView.contentSize.height < descriptionTextView.bounds.height {
        self.readMoreLabel.snp.updateConstraints { (make) -> Void in
            make.height.equalTo(0)
        }
    }
}

Can anyone advise how I can achieve a check that will be able to calculate if the content of the uitextview is less than 4 lines somehow?

jwarris91
  • 902
  • 9
  • 24
  • Possible duplicate of [Counting the number of lines in a UITextView, lines wrapped by frame size](https://stackoverflow.com/questions/5837348/counting-the-number-of-lines-in-a-uitextview-lines-wrapped-by-frame-size) – DonMag Jun 26 '19 at 16:21
  • im afraid this solution didnt work for me, it returns either 1 or 2 lines when there are 4 (and more if it was unlimited) – jwarris91 Jun 26 '19 at 16:35

1 Answers1

0

Based on the discussion here: Counting the number of lines in a UITextView, lines wrapped by frame size

This seems to work reliably for my testing:

func getNumberOfLines(in textView: UITextView) -> Int {

    let numberOfGlyphs = textView.layoutManager.numberOfGlyphs
    var index = 0, numberOfLines = 0
    var lineRange = NSRange(location: NSNotFound, length: 0)

    while index < numberOfGlyphs {
        textView.layoutManager.lineFragmentRect(forGlyphAt: index, effectiveRange: &lineRange)
        index = NSMaxRange(lineRange)
        numberOfLines += 1
    }

    return numberOfLines
}
DonMag
  • 69,424
  • 5
  • 50
  • 86
  • hmm this doesnt work for me, perhaps its due to timings when setting the content – jwarris91 Jun 26 '19 at 17:09
  • When are you trying to use it? – DonMag Jun 26 '19 at 17:22
  • its called in a configure function that runs after instantiation of the view, – jwarris91 Jun 27 '19 at 08:29
  • @jwarris91 - you won't be able to get the number of lines until *after* auto-layout has determined the width of the textView. It sounds like you are trying to get it before that happens. Is the textView in a tableView cell? – DonMag Jun 27 '19 at 11:50
  • its the view of a tableview cell, im converting it for use somewhere else in the app where it needs to be a UIView – jwarris91 Jun 27 '19 at 15:19