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

前端 未结 13 1419
逝去的感伤
逝去的感伤 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 04:06

    I found the perfect solution to this problem in Apple's Text Layout Programming Guide. Here is the solution Apple provides:

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

    This could easily be written into an extension for UITextView, or as a standalone method taking in a UITextView object as a parameter

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

    Improved and update Luke Chase's answer to Swift 5, XCode 11, iOS 13 to get text view number of lines and autoresize table view cell height.

    1. You can use storyboard with static cell height to design it as you want. Make UITextView scroll enable: false (disable scroll).

    2. In viewDidLoad add your estimated row height and your textView delegate.

    override func viewDidLoad() {
            super.viewDidLoad()
    
            quoteTextView.delegate = self
            tableView.estimatedRowHeight = 142
    
        }
    
    1. Add table view delegates for heightForRowAt:
    override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        return UITableView.automaticDimension
    }
    
    1. Conform to UITextViewDelegate to listen when user inputs text.
    extension ViewController: UITextViewDelegate {
        func textViewDidChange(_ textView: UITextView) {
            // Refresh tableView cell
            if textView.numberOfLines > 2 { // textView in storyboard has two lines, so we match the design
                // Animated height update
                DispatchQueue.main.async {
                    self.tableView?.beginUpdates()
                    self.tableView?.endUpdates()
                }
            }
        }
    }
    
    1. Add UITextView extension so you avoid redundant code and use all over the app.
    extension UITextView {
        var numberOfLines: Int {
            // Get number of lines
            let numberOfGlyphs = self.layoutManager.numberOfGlyphs
            var index = 0, numberOfLines = 0
            var lineRange = NSRange(location: NSNotFound, length: 0)
    
            while index < numberOfGlyphs {
                self.layoutManager.lineFragmentRect(forGlyphAt: index, effectiveRange: &lineRange)
              index = NSMaxRange(lineRange)
              numberOfLines += 1
            }
    
            return numberOfLines
        }
    }
    

    -> Do not forgot to disable uitextview scroll. Cheers!<-

    Preview

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

    This variation takes into account how you wrap your lines and the max size of the UITextView, and may output a more precise height. For example, if the text doesn't fit it will truncate to the visible size, and if you wrap whole words (which is the default) it may result in more lines than if you do otherwise.

    UIFont *font = [UIFont boldSystemFontOfSize:11.0];
    CGSize size = [string sizeWithFont:font 
                          constrainedToSize:myUITextView.frame.size 
                          lineBreakMode:UILineBreakModeWordWrap]; // default mode
    float numberOfLines = size.height / font.lineHeight;
    
    0 讨论(0)
  • 2020-11-27 04:08

    You need to use the lineHeight property, and font lineHeight:

    Objective-C

    int numLines = txtview.contentSize.height / txtview.font.lineHeight;
    

    Swift

    let numLines = (txtview.contentSize.height / txtview.font.lineHeight) as? Int
    

    I am getting correct number of lines, hope it help you also.

    0 讨论(0)
  • 2020-11-27 04:11
       func numberOfLines(textView: UITextView) -> Int {
        let layoutManager = textView.layoutManager
        let numberOfGlyphs = layoutManager.numberOfGlyphs
        var lineRange: NSRange = NSMakeRange(0, 1)
        var index = 0
        var numberOfLines = 0
    
        while index < numberOfGlyphs {
            layoutManager.lineFragmentRect(forGlyphAt: index, effectiveRange: &lineRange)
            index = NSMaxRange(lineRange)
            numberOfLines += 1
        }
        return numberOfLines
    }
    

    Working Fine for me

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

    Swift 5.0

    extension UITextView {
        func sizeFit(width: CGFloat) -> CGSize {
            let fixedWidth = width
            let newSize = sizeThatFits(CGSize(width: fixedWidth, height: .greatestFiniteMagnitude))
            return CGSize(width: fixedWidth, height: newSize.height)
        }
    
        func numberOfLine() -> Int {
            let size = self.sizeFit(width: self.bounds.width)
            let numLines = Int(size.height / (self.font?.lineHeight ?? 1.0))
            return numLines
        }
    }
    
    0 讨论(0)
提交回复
热议问题