2

The Goal

I have an NSTableView in my app and I'd like to draw "overlapping" rows to create a "connecting" effect like that in Automator.app:

screenshot of automator app


What I'm Trying

The approach I'm considering is to use NSTableView's -(NSRect)frameOfCellAtColumn:(NSInteger)columnIndex row:(NSInteger)rowIndex method to increase the Y-origin of all rows after the first. My tableView is view-based and it does NOT use auto-layout.

My question is: is that the correct way to achieve this effect? It seems "dangerous" to have the tableView draw rows with overlapping frames and I can't figure out if this is going to result in a bunch of extra blank space at the bottom of the tableView (because the tableView doesn't take the overlapping frames into account when calculating its overall height; it just uses the sum of the rowHeight value from each row.)

Does anyone know if there's a different, canonical way to achieve the effect from the Automator tableView?

Bryan
  • 4,628
  • 3
  • 36
  • 62
  • 2
    Instead of having the cells overlap, why don't you just include the tip of the triangle in the background image for the cell with the rounded top part. This creates the illusion of overlapping without the complexity – Patrick Goley Jul 18 '16 at 23:05
  • I considered that approach. But when I looked at Automator, that's definitely not how Apple's doing it. If you drag one of the rows, it's clear that the triangle and half-circle are part of the cellViews themselves rather than drawn in the background. The selection highlight also draws a nice blue border around the triangle/half-circle that continues naturally into the cell's border. And, since the cells are "collapsible" in both Automator and my app, calculating the precise point to do the fake drawing in the background becomes really tough. – Bryan Jul 19 '16 at 02:18
  • The issue, though, is that you have no reason to believe that Automator is using a table view rather than, say, a (custom?) stacking view. So, asking for advice on how to replicate that with a table view ties the hands of the potential responders. – Ken Thomases Jul 19 '16 at 06:08
  • True; I can't prove it's not another class. But it's got all the mechanics of NSTableView. And when you drag a row, the row suddenly "snaps" down to where it would be positioned if it did not overlap. That leads me to believe there's some sorcery going on that simply adjusts frames. – Bryan Jul 19 '16 at 17:26

1 Answers1

4

As Patrick Goley suggested, I think you should fake it by drawing the connection point as part of the background or a table view separator.

Apple's HoverTableDemo sample illustrates some of the techniques and the WWDC 2011 session 120 video "View Based NSTableView Basic to Advanced" describes them in more detail.

I think you would set the table view's intercellSpacing to accommodate the connection point image size. You would set the gridStyleMask to include NSTableViewSolidHorizontalGridLineMask.

You would use a custom subclass of NSTableRowView to do the custom drawing of the background and separators (between the rows). You'd override -drawBackgroundInRect: and -drawSeparatorInRect: for those.

You would use a custom sublcass of NSTableView to do custom drawing of the grid beyond the end of the rows, which might just be the arrow off the bottom of the last row, if you want one. You would override -drawGridInClipRect: to do that.

Ken Thomases
  • 88,520
  • 7
  • 116
  • 154
  • See comment on the original question for why I didn't go this route. (It was my first thought as well.) – Bryan Jul 19 '16 at 02:18