1

So I'm trying to get the lineFragment size for each line in a UITextView's NSLayoutManager. On the first load, it provides values which are larger than the textView layouts.

I have a textview which fills the ViewControllers view with Autolayout.
A basic example is this:

let demotext = """ <Multiline String> """
override func viewWillAppear(_ animated: Bool) {
    textview.text = demotext
}

func size(text: String) {   
    let layoutManager = textview.layoutManager
    let numberOfGlyphs = layoutManager.numberOfGlyphs
    var currentGlyph = 0
    while currentGlyph < numberOfGlyphs {
        var glyphRange = NSRange()
        let lineSize = layoutManager.lineFragmentUsedRect(forGlyphAt: currentGlyph, effectiveRange: &glyphRange)
        print("linesize: \(lineSize)")
            
        currentGlyph = NSMaxRange(glyphRange)
    }
}

I tried placing the call in viewDidLoad, viewDidLayoutSubviews, viewWillAppear and also wrote a delegate (which only works if you set allowsNonContiguousLayout to false) to react on layoutManager(_ layoutManager: didCompleteLayoutFor: atEnd:).

The output for the first line after the first start is as follows:
linesize: (0.0, 0.0, 125.6982421875, 16.70703125)

Rotating once to the right and back results in:
linesize: (0.0, 0.0, 107.828125, 13.8)

The line is shorter than the device width, so rotating to landscape once would be enough (it's the same size).

The second value is correct. (I have a visual effect for the text to be able to identify it directly).

I guess I'm missing something basic. Any ideas what it is?

Thanks

Edit:// creating the textview programatically instead of IB solves the problem. But I'm still trying to figure out, why using IB results in this behavior.

Edit2:// This problem does not appear on macOS just iOS

Jan
  • 1,827
  • 2
  • 16
  • 29

0 Answers0