Counting the number of lines in a UITextView, lines wrapped by frame size

前端 未结 13 1411
逝去的感伤
逝去的感伤 2020-11-27 03:42

I wanted to know when a text is wrapped by the frame of the text view is there any delimiter with which we can identify whether the text is wrapped or not.

For insta

相关标签:
13条回答
  • 2020-11-27 03:55

    Use this (where _text_v is your text view):

    -(NSInteger) linesCount {
        return _text_v.contentSize.height/_text_v.font.lineHeight;
    }
    
    0 讨论(0)
  • 2020-11-27 03:58

    Swift 3:

    let layoutManager:NSLayoutManager = textView.layoutManager
    let numberOfGlyphs = layoutManager.numberOfGlyphs
    var numberOfLines = 0
    var index = 0
    var lineRange:NSRange = NSRange()
    
    while (index < numberOfGlyphs) {
        layoutManager.lineFragmentRect(forGlyphAt: index, effectiveRange: &lineRange)
        index = NSMaxRange(lineRange);
        numberOfLines = numberOfLines + 1
    }
    
    print(numberOfLines)
    
    0 讨论(0)
  • 2020-11-27 03:59

    I think that you can try to use NSLayoutManager:

    NSLayoutManager *layoutManager = [textView layoutManager];
    unsigned numberOfLines, index, numberOfGlyphs =
            [layoutManager numberOfGlyphs];
    NSRange lineRange;
    for (numberOfLines = 0, index = 0; index < numberOfGlyphs; numberOfLines++){
        (void) [layoutManager lineFragmentRectForGlyphAtIndex:index
                effectiveRange:&lineRange];
        index = NSMaxRange(lineRange);
    }
    

    Ref

    CountLines

    0 讨论(0)
  • 2020-11-27 04:02

    Swift 4 version of Luke Chase's answer

    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
    }
    
    0 讨论(0)
  • 2020-11-27 04:02

    I spent a lot of time trying to calculate in real time the number of lines for an input TextView (say a chat text entry box) and the only solution that works in such a case is Luke Chase's (for some reason the frame.height approach appears to update only ever 3rd or fourth letter typed into a textView and so is not accurate).

    As a commenter mentioned however, there is a small bug in which a user generated line breaks ("\n" or keyboard return press) are not properly accounted for. Even stranger, it only "misses" the first such line-break, any subsequent ones are correctly captured (say you go to the line 4 times it will return only 3 lines clearly missing the first line break).

    So to go around that bug I simple look record the first such line-break (character "\n") and manually add a line to the # of lines that the gliph method returns.

    In code that gives:

        func offSetTableViewIfNeeded() {
        let numberOfGlyphs = textView.layoutManager.numberOfGlyphs
        var index : Int = 0
        var lineRange = NSRange(location: NSNotFound, length: 0)
        var currentNumOfLines : Int = 0
        var numberOfParagraphJump : Int = 0
    
        while index < numberOfGlyphs {
            textView.layoutManager.lineFragmentRect(forGlyphAt: index, effectiveRange: &lineRange)
            index = NSMaxRange(lineRange)
            currentNumOfLines += 1
    
            // Observing whether user went to line and if it's the first such line break, accounting for it.
            if textView.text.last == "\n", numberOfParagraphJump == 0 {
                numberOfParagraphJump = 1
            }
        }
    
        currentNumOfLines += numberOfParagraphJump
    
        print("Number of lines is:", currentNumOfLines)
    

    Hope this helps others who've been struggling with the super weird behavior of input textView (can't understand why Apple does not provide a # of line method out of the box!).

    0 讨论(0)
  • 2020-11-27 04:03

    Swift extension:

    Using @himanshu padia answer

    //MARK: - UITextView
    extension UITextView{
    
        func numberOfLines() -> Int{
            if let fontUnwrapped = self.font{
                return Int(self.contentSize.height / fontUnwrapped.lineHeight)
            }
            return 0
        }
    
    }
    

    Usage : yourTextView.numberOfLines()

    be aware that if for some reason the font of the text view is nil, the return will be zero.

    0 讨论(0)
提交回复
热议问题