Using Autolayout with expanding NSTextViews
autolayout, cocoa, nstextview, osx-lion
Solution
I had a similar problem with an NSTextField, and it turned out that it was due to the view wanting to hug its text content tightly along the vertical orientation. So if you set the content hugging priority to something lower than the priorities of your other constraints, it may work. E.g.:
[textView setContentHuggingPriority:NSLayoutPriorityFittingSizeCompression-1.0 forOrientation:NSLayoutConstraintOrientationVertical];
And in Swift, this would be:
setContentHuggingPriority(NSLayoutConstraint.Priority.fittingSizeCompression, for:NSLayoutConstraint.Orientation.vertical)
Problem
My app consists of an `NSScrollView` whose document view contains a number of vertically stacked `NSTextViews` — each of which resizes in the vertical direction as text is added. Currently, this is all managed in code. The `NSTextViews` resize automatically, but I observe their resizing with an `NSViewFrameDidChangeNotification`, recalc all their origins so that they don't overlap, and resize their superview (the scroll view's document view) so that they all fit and can be scrolled to. This seems as though it would be the perfect candidate for autolayout! I set `NSLayoutConstraints` between the first text view and its container, the last text view and its container, and each text view between each other. Then, if any text view grows, it automatically "pushes down" the origins of the text views below it to satisfy contraints, ultimately growing the size of the document view, and everyone's happy! Except, it seems there's no way to make an `NSTextView` automatically grow as text is added in a constraints-based layout? Using the exact same `NSTextView` that automatically expanded as text was entered before, if I don't specify a constraint for its height, it defautls to 0 and isn't shown. If I do specify a constraint, even an inequality such as >=20, it stays stuck at that size and doesn't grow as text is added. I suspect this has to do with NSTextView's implementation of `-intrinsicContentSize`, which by default returns `(NSViewNoInstrinsicMetric, NSViewNoInstrinsicMetric)`. So my questions: if I subclasses `NSTextView` to return a more meaningful `intrinsicContentSize` based on the layout of my text, would my autolayout then work as expected? Any pointers on implementing `intrinsicContentSize` for a vertically resizing NSTextView?