NSTableView, NSArrayController and reload only after key press?
I have the following situation:
- There is one custom view inside of the first window that contains a NSTableView.
- There is a second window which acts as a form for the current object behind the selection of the table view inside the first window.
Some more details:
- I’ve implemented the setDoubleAction: behavior in the NSTableView that basically opens the second window
- The table view is bound to the 开发者_开发问答arrangedObjects of an (subclassed) NSArrayController
- The specific interface elements in the second window (that opens on double click) are bound to the selection of the NSArrayController
- I’ve subclassed the NSArrayController and modified the following functions:
At first I changed addObject: (or add:, this doesn’t really matter):
- (void)addObject:(id)object
{
[super addObject:object];
[self saveTemplatesToDisk];
}
Then I changed remove:
- (void)remove:(id)sender
{
[super remove:sender];
[self saveTemplatesToDisk];
}
- The action that opens the preference sheet is just a one liner:
[NSApp beginSheet:preferenceWindow modalForWindow:[_preferenceView window] modalDelegate:nil didEndSelector:NULL contextInfo:NULL];
- The code that get’s executed after the user presses the return key / OK button isn’t complicated either.
It just saves the current content of the array controller to disk and closes the second window:
- (IBAction)endPreferenceSheet:(id)sender
{
[templateArrayController saveTemplatesToDisk];
[NSApp endSheet:preferenceWindow];
[preferenceWindow orderOut:nil];
}
Finally here’s my problem / question
When I press the return key in the second window, the window closes, the data gets saved and the NSTableView gets properly reloaded without any further interaction. But when I press on the OK button with the mouse, nothing seems to happen. Here’s the interesting part: when I now select another row in the table view in the first window after the second window disappeared, the previously selected row (read: the updated object) gets properly reloaded and displays the content I’ve edited in the second window that has interface elements bound to the selection.
Basically my implementation works, but not when the user uses the mouse to close the window.
The only difference I can spot is the currentEvent, but I can’t imagine how this could change the behavior of this simple application.
- When I press the OK button with the mouse:
NSEvent: type=LMouseUp loc=(563.055,30.1484) time=58450.2 flags=0 win=0x0 winNum=5371 ctxt=0x0 evNum=8093 click=1 buttonNumber=0 pressure=0 subtype=NSTabletPointEventSubtype deviceID=0 x=19469 y=15838 z=0 buttons=0x0 pressure=0.000000 tilt={0.453108, -0.140629} rotation=0.000000 tangentialPressure=0.000000 vendor1-3=(0, 0, 0)
- When I press return:
NSEvent: type=KeyDown loc=(0,300) time=58474.8 flags=0 win=0x0 winNum=5371 ctxt=0x0 chars=" " unmodchars=" " repeat=0 keyCode=36
Any ideas how I can solve my problem?
Remember the responder chain: The keyboard event starts at the first responder, which will be the field editor, then (if that doesn't handle it) goes to the next responder, which will be the table view. The mouse event goes directly to the view that the user clicked on, which is the button.
So, the difference is that the table view handles the return event, but it never sees the mouse event. When the user clicks, you simply get an action message from the button—the table view remains in in editing mode.
The solution is to have the action method tell the controller to commit editing before proceeding with the actual action.
精彩评论