Code Sample
I have a NSLayoutManager, NSTextContainer & NSTextStorage
as properties in a custom NSView
(not a TextView) initialized in awakeFromNib()
as follows:
textStorage = NSTextStorage(attributedString: self.attributedString)
layoutManager = NSLayoutManager()
textContainer = NSTextContainer(containerSize: NSMakeSize(self.frame.size.width, 1))
layoutManager.addTextContainer(textContainer)
textStorage.addLayoutManager(layoutManager)
layoutManager.glyphRangeForTextContainer(textContainer)
The vertical containerSize
of the NSTextContainer
is deliberately set to 1 to see if it has the expected effect of hiding the text being rendered - it does not! It is making NO difference in the rendering of this text in the view - which is the subject of the question!
In drawRect
I include the lines below to draw the text:
let glyphRange = layoutManager.glyphRangeForTextContainer(textContainer)
self.lockFocus()
layoutManager.drawGlyphsForGlyphRange(glyphRange, atPoint: NSMakePoint(0, 0))
self.unlockFocus()
Findings
- It appears best to work with your custom view in a flipped co-ordinate system like the
NSTextView
else I feel like I'm going to be in for a world of pain! Irrespective of this, NSLayoutManager always starts drawing its text internally in a flipped co-ordinate system (just likeNSTextView
) - The
containerSize.width
property ofNSTextContainer
has the following effect: it is binding on a line level for all levels including the first (I know it's obvious but stick with me...) - The
containerSize.height
property ofNSTextContainer
has a curve-ball: it will NOT be binding on the first line even if the containing view does not have the room to display it vertically BUT will be binding on subsequent lines
*it took me a long time to come to this hypothesis about containerSize.height
because I was only drawing one line! *
Question
- Are my conclusions regarding
NSTextContainer
correct? - What is the best way to control text drawing from a vertical perspective? I am wanting to place my single line of the text at the bottom of the view (and not have it floating at the top as in the default)