[ 2005-March-02 11:37 ]
Apple's Cocoa library contains two very good table controls, NSTableView and it's close relative, NSOutlineView. However, both of these controls have one large limitation: All the rows must be the same height. This is an issue when displaying table cells with content that varies in height, such as large amounts of text or images. Luckily, Apple's Cocoa controls were also very well designed, making it possible to add this functionality simply by subclassing the table views. RowResizableTableView is an NSTableView subclass which allows each row to have variable heights, and RowResizableOutlineView is an NSOutlineView subclass with the same functionality. Updated: Fixed some bugs, changed licence to BSD, added some new links to products that use it.
Download RowResizableViews disk image
RowResizableViews Demo Application
Users of RowResizableTableView
RowResizableTableView/RowResizableOutlineView Features
- Completely compatible with NSTableView or NSOutlineView
- As subclasses, RowResizableTableView and RowResizableOutlineView support the same features and interfaces as NSTableView and NSOutlineView. Adding resizable rows to your program is as easy as replacing the Application Kit class with the resizable version.
- Rows automatically fit themselves to each cell's contents
- The views automatically size their rows to fit the contents of the cells. If the contents change or are edited, the row heights will be updated automatically.
- Editing text works as expected
- When editing text in one of the cells in the table, the row will automatically size itself to fit the wrapped text, and the text editor will resize as expected.
- Unrestrictive open source licence (BSD)
- You get all the source code, and can use the classes in commercial or noncommercial projects.
RowResizableTableView/RowResizableOutlineView Disadvantages
- The table's data source must be fast
- In order to size the table and the scroll bars correctly, RowResizableTableView queries all the cells in the table for their sizes more often than NSTableView. If the data source is slow, or your table is very large, this will be a major performance hit.
- Performance
- Due to the need to query rows for their heights and to lookup row heights in a table instead of performing simple calculations, RowResizableTableView is slower than NSTableView when redrawing. However, if the data source is fast and the table is not too large, the difference should not be significant. At this point, the class has not been optimised at all, and there is lots of room for improvement. If the performance is an issue, please contact me and I would be happy to tune the code for you.
How to use RowResizableTableView/RowResizableOutlineView
- Download the code.
- Add
RowResizable*
to your project.
- Replace your NSTableView/NSOutlineView class with RowResizableTableView/RowResizableOutlineView. This can be done inside Interface Builder by importing the .h file and then going to the "custom class" pane of the table view's information window.
- Build and run. Please report any problems.
Files
- RowResizableViews.dmg.bz2
- Includes the compiled demo application and the complete source code.
TODO List
- Test the class more thoroughly to make sure it is "drop in" compatible with NSTableView/NSOutlineView.
- When editing a cell and the text insertion point falls out of the visible area, automatically scroll the table to keep it visible.
- When live resizing, the automatic text wrapping sometimes makes for some weird drawing effects.
- It currently must be created from a NIB. I need to support manual creation.
- "automatically fits cell contents" should be a configurable option.
- "automatically wraps text in cell" should be a configurable option.
- Make a nice interface for manually sizing rows?