On 6/4/2015 19:39, Graham Cox wrote:
On 5 Jun 2015, at 9:19 am, Frank D. Engel, Jr. <fde...@fjrhome.net> wrote:

- (void)browser:(NSBrowser *)browser willDisplayCell:(MyBrowserCell *)cell 
atRow:(NSInteger)row column:(NSInteger)column
{
     // Find the item and set the image.
     WhateverObject *c = [browser itemAtRow:row inColumn:column];
     [cell bind:@"image" toObject:c withKeyPath:@"icon" options:nil];
}

This looks wrong to me.

If you have the source object (c) and the cell that is to display the image 
(cell), why not just set the image directly?

[cell setImage:[c icon]];

The binding might help when the “icon” property changes, but setting up the 
binding here (which is effectively within a call to -drawRect: of the 
NSBrowser) is almost certainly incorrect. The binding needs to be set up 
outside of the drawing pathway, but since cells are annoying things, just 
binding the cell’s image to the icon property won’t work - the cell won’t 
automatically refresh the relevant part of the browser view.

Cells generally don’t update their host views on a change, because they’re 
designed to be reusable in a lot of different circumstances - the view uses the 
cell to draw some content, but the cell is unaware of which view it belongs to 
so there isn’t a general way for a cell to update its host view. It’s also 
undesirable, because many classes such as NSTableView and NSBrowser set up the 
cell’s state (properties) on the fly just before the cell is drawn, so if the 
cell dirtied the view when that happened you’d get an infinite redraw cycle.

So what you need to do is to have a property or method on your browser 
controller that sets the relevant cell’s image property AND refreshes the 
correct part of the view, then bind that controller method to the object’s icon 
property.

—Graham

P.S. Cells in general are deprecated, so getting away from code that requires 
them is the way of the future.

If I don't bind from there, I'm not sure where else to do it from? Originally I was just doing a setImage: method call there, but I changed it to a bind to fix the first issue I listed earlier (this is why it updates more readily now when I keep it up).

In the future, I will be expanding the use of the "icon" to show it in places besides the browser - I am considering the "icon" to be a calculated part of the data model, with the "image" being part of one view which I expect to later be many views against the same object, so trying to update from within the source object isn't going to work unless I reinvent the wheel and basically recreate the bindings or some other notification mechanism.

The update of the icon is based on any of several properties of the source object changing dynamically, sometimes by the user, and sometimes from a method triggered an NSTimer (I am conditionally animating some of these properties), and since the set of views against the object is likely to change periodically while the application is running (and quite possibly in the middle of those animations), with some views potentially changing which objects they represent, I was hoping to avoid having to stoop to that level (and didn't expect that I would need to) - but I will if that is what it takes.

I'll work with that a bit more.


I still need a pointer of some kind with the NSPopupButtonCell question.


_______________________________________________

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

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:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Reply via email to