views:

53

answers:

1

I have a menu which has an item for each value in an enum.

The menu:

[ ] Sort by Due Date
[ ] Sort by Priority
[√] Sort by Title

The enum:

typedef enum  CW_TASK_SORT_METHOD {
    CWTaskSortMethodDueDate,
    CWTaskSortMethodPriority,
    CWTaskSortMethodTitle
} CWTaskSortMethod;

The property:

@property(readwrite, assign) CWTaskSortMethod taskSortMethod;

What's the cleanest way to wire this up? I have two ideas but both strike me as unsatisfactory.

1st idea: Create properties for each value (sortMethodIsDueDate, setSortMethodIsDueDate: etc) These properties would call setTaskSortMethod: and call valueDidChange:@"sortMethodIsDueDate" etc. The menu items would then bind to these properties. This seems like a lot of work.

2nd idea: Connect each menu item to -(IBAction)updateSortMethod:(id)sender which could then iterate the menu items and set the value depending on sender. This approach is fine until taskSortMethod is changed by a different section of code at which point code needs to be added to keep the menu in sync with taskSortMethod.

I'm leaning towards the first approach as it has better separation between the V & C.

Any better ideas?

+2  A: 

I think you're on the right track with your second idea, but there's something to consider:

NSMenu / NSMenuItem don't have a concept of "selected item" like NSPopUpButton for instance. I'd use the target/action mechanism to change the sort method and menu validation ( http://tinyurl.com/ydejs27 ) or even the NSMenu delegate method -menu:updateItem:atIndex:shouldCancel: ( http://tinyurl.com/ya324yv ) to update the state of the item based on the result of -taskSortMethod.

Since the menu items only need to be updated when they're shown (which this mechanism does for you), you don't have to worry about updating the menu items yourself when -taskSortMethod changes elsewhere.

Ex:

[sortByDueDateMenuItem setState: ([self taskSortMethod] == CWTaskSortMethodDueDate) ];

IMO, this is a lot cleaner than trying to over-engineer a bindings-powered solution.

Joshua Nozzi
I've gone with the 2nd approach. I think the next time this problem comes up I'll create a class to address it. I'm surprised there isn't a more elegant solution.
Benedict Cohen