Joris Kluivers

I like to build software.


While trying to duplicate the RuleView used by Apple in the Finder for example I ran into the problem of resizing views. The RuleView needs to grow in size when a new rule is added. Each view following the RuleView needs to be resized to to create space for the RuleView. Since layout in InterfaceBuilder works using springs, but you can’t attach two edges of view together, I created a helper view called JKDistributedView which helps me resize and reposition it’s children views.

To use JKDistributedView you add a NSView subclass to Interface Builder and set it’s custom class to JKDistributedView. Every nsview added to JKDistributedView will be layout according to the following rules:
  • top to bottom
  • Every view will get it’s preferred height
  • When a views vertical springs are dynamic the view will fill all remaining vertical space after the fixed height views are sized.
When a rule is added to the JKRuleView it needs to grow in size. JKRuleView calls descendantFrameChanged: on it’s parent view (JKDistributedView) to indicate all children of JKDistributedView need to be resized and repositioned.

So the finder smart folder view would be created using 3 views as subviews in a JKDistributedView. The JKRuleView, the NSOutlineView (using a dynamic vertical resize hint) and a third view at the bottom to display the path of the selected file. JKDistributedView makes sure the JKRuleView and the path view have a fixed size, the NSOutlineView will fill all space in between. Now when you click the add button in the JKRuleView a new rule will be added, JKDistributedView will increase JKRuleViews height and decrease the height of the NSOutlineView