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?
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 (Introduction to User Interface Validation) or even the NSMenu delegate method -menu:updateItem:atIndex:shouldCancel: (NSMenuDelegate Protocol Reference) 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.