NSOutlineView floating group row question - SOLVED
NSOutlineView floating group row question - SOLVED
- Subject: NSOutlineView floating group row question - SOLVED
- From: Bill Cheeseman <email@hidden>
- Date: Sun, 17 Aug 2014 11:17:48 -0400
Back on June 14, 2014, I posted this question:
"I have a view-based NSOutlineView with the Floats Group Rows setting turned on in Interface Builder. The outline view is the one supplied by the Source List object in the Xcode 5.1.1 Interface Builder library. It has Highlight set to the Source List style, and it includes two NSTableCellViews, one for the outline view's group rows and one for its regular rows.
"It works fine, except for one thing: When the regular rows are scrolled under a "sticky" group row at the top of the outline view, the text of the normal rows is not dimmed. The visual effect is therefore terrible, because the words in the group row and the words in the underlying normal row are the same intensity.
"In all of the examples I see, the underlying text is dimmed or faded by a substantial amount, for a nice visual effect. See for example Apple's TableViewPlayground sample code and the PXSourceList example at <https://github.com/Perspx/PXSourceList>. Examining the code and nib file settings in those examples, I don't see anything special to account for the dimming.
"Can anybody explain the trick to me? I must be overlooking something in those examples.
I have now solved the problem. I was wrong about the examples -- they do not dim rows sliding under a floating group row in a source list, but instead slide rows under a semi-transparent top row in a normal table view column, as in a Finder window in List View mode.
The solution involves calculating the rect for what I call the "work area" of the source list, the area below the floating group row at the top of the source list and above some floating buttons at the bottom of the source list. This is similar to the built-in -[NSView visibleRect], but shorter at the top and bottom. My custom -updateRowViewAppearance method is called in several places in my source list controller, whenever insertion or removal of rows creates a need to dim rows that move under the floating group row just above the "work area", and especially in an override of -[NSScrollView reflectScrolledClipView:], which AppKit calls whenever resizing or scrolling necessitates redrawing the scroll bars. My -updateRowViewAppearance calls two methods that dim and undim rows that are outside the "work area." Here are the important methods:
- (void)reflectScrolledClipView:(NSClipView *)clipView {
// Sends -[AWRSourceListViewController updateRowViewAppearance] to dim or undim the contents of outline view rows at the top of the source list.
// Invoked automatically while the scroll view's document view is scrolling and when the content view's relationship to its document view changes. This makes it unnecessary for AWRSourceListViewController to observe NSViewBoundsDidChangeNotification or NSViewFrameDidChangeNotification or to implement the -outlineView:didAddRowView:forRow:, -outlineView:didRemoveRowView:forRow:, -outlineViewItemDidCollapse:, or -outlineViewItemDidExpand: NSOutlineViewDelegate protocol methods.
// Allow super to update the source list's scroll bars.
[super reflectScrolledClipView:clipView];
// Dim or undim the contents of outline view rows at the top of the source list. The documentView is the source list's outline view, and its delegate is the source list view controller AWRSourceListViewController.
[[[self documentView] delegate] updateRowViewAppearance];
}
- (void)dimRowView:(NSTableRowView *)rowView {
// Dims rowView, including its disclosure triangle, if any, and the contents of its cell view. Sent by -updateRowViewAppearance.
NSInteger index = [[self sourceListOutlineView] rowForView:rowView];
if (!([rowView isGroupRowStyle] && [self rowIsAboveWorkRect:index])) {
[rowView setAlphaValue:0.15];
}
}
- (void)undimRowView:(NSTableRowView *)rowView {
// Undims rowView, including its disclosure triangle, if any, and the contents of its cell view. Sent by -updateRowViewAppearance.
NSInteger index = [[self sourceListOutlineView] rowForView:rowView];
if (!([rowView isGroupRowStyle] && [self rowIsAboveWorkRect:index])) {
[rowView setAlphaValue:1.0];
}
}
I experimented with animating the dimming and undimming of the rows. I like the resulting appearance better, but I haven't yet figured out how to avoid the animation's interfering with scrolling to yield a sometimes jerky appearance.
--
Bill Cheeseman - email@hidden
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden