Re: Images in NSOutlineView disappear on dataReload
Re: Images in NSOutlineView disappear on dataReload
- Subject: Re: Images in NSOutlineView disappear on dataReload
- From: Ken Thomases <email@hidden>
- Date: Mon, 16 Nov 2015 19:01:26 -0600
On Nov 13, 2015, at 11:48 AM, Nick <email@hidden> wrote:
>
> I've encountered a strange behavior in a source list NSOutlineView.
> Basically, whenever I call "reloadData", an image, that was set for a
> currently selected row (NSTableCellView's imageview.image), disappears (I
> set image in outlineView:viewForTableColumn:item:). When I select the row,
> the image appears again …
Source lists are a bit strange, in a couple of ways.
First, NSTableCellView does some special stuff in its override of -viewWillDraw. Based on the rowSizeStyle, it will adjust the layout of the text field and image view. It will also tweak their properties to match the standard source list style.
This layout overrides whatever is done by auto layout, at least for the current drawing pass, because -viewWillDraw happens after layout but before drawing.
However, in recent versions of OS X, the table cell view doesn't get redrawn as often as you might think. I suspect that the use of NSVisualEffectView and a layer-backed view hierarchy results in the cells being drawn once into a layer and then refreshed from there from then on. Changing the content of the text field or image view causes those subviews to redraw themselves, but does not cause the table cell view itself to redraw, so it doesn't repeat the layout in -viewWillDraw.
So, I think that you have an auto layout issue in your table cell view. It results in the image view being misplaced and/or sized to (0, 0). The table cell view is hiding this problem by doing manual layout, but that only happens on certain occasions. In between those occasions, auto layout can kick in and undo what the table cell view did.
You should consider turning auto layout off for the table cell view's subviews. That is, set translatesAutoresizingMaskIntoConstraints to true, set the autoresizingMask, set the frame (although NSTableCellView will override that for the text field and image view), and remove / don't add any constraints. If you want to add additional subviews in your cell view, you'll need to use a custom subclass of NSTableCellView and override -viewWillDraw to adjust the layout after the superclass has had its chance. See <https://developer.apple.com/library/mac/samplecode/SidebarDemo/Listings/SidebarTableCellView_m.html> for an example of this. (Notice how it requires the sort of view frame computation that auto layout was supposed to eliminate.)
The fact that source list layout is incompatible with auto layout is the first bug. The fact that it relies on -[NSTableCellView viewWillDraw] and that's no longer being called as often as necessary to keep the layout override in force is the second bug. (Arguably, it should use an override of -layout for the layout parts. I don't know where a good place would be to tweak the text field and image view properties. Probably in the -setRowSizeStyle:, -setTextField:, and -setImageView: setters.)
Regards,
Ken
_______________________________________________
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