Saving NSManagedObjectContext causes NSTextField to lose focus

This is a really strange problem that I see in my application. I have an NSTextField associated with an attribute of an NSManagedObject, but whenever the object is saved, the text field loses focus. I am constantly updating the binding value, so this is far from ideal.

Has anyone seen anything like this before and (hopefully) found a solution?

+4
source share
3 answers

Okay, so thanks to Martin, indicating that I should read the documents a little closer. This is the expected behavior, and here is what I did to get around it (use your opinion on whether this suits you):

I save my context once every 3 seconds, checking at the beginning if the context has any changes before I start the actual save: method on my NSManagedObjectContext . I added a simple increment / decrement NSUInteger ( _saveDisabler ) to the Core Data controller class, which changes in the following ways:

 - (void)enableSaves { if (_saveDisabler > 0) { _saveDisabler -= 1; } } - (void)disableSaves { _saveDisabler += 1; } 

Then, everything I do in my usual saveContext method does a simple check at the top:

 if (([moc hasChanges] == NO) || (_saveDisabler > 0)) { return YES; } 

This prevents saving from occurring and means that the focus is not stolen from any of my subclasses of the custom text field. For completeness, I also subclassed NSTextField and turned on / off saving in my Core Data controller in the following ways:

 - (void)textDidBeginEditing:(NSNotification *)notification; - (void)textDidEndEditing:(NSNotification *)notification; 

It may be a little dirty, but it works for me. I really want to hear about cleaner / less complicated methods if someone did it successfully differently.

+3
source

I recently ran into a problem and fixed it by changing the way NSTextField is bound to the NSManagedObject attribute. Instead of binding the value of the text field to the selection. [Attribute] NSArrayController key path, I bound arrayController.selection. [Attribute] keyPath of the view controller that had the correct output pointing to the controller.

For some reason, NSTextField will not lose focus when an NSManagedObjectContext is saved if it is connected in this way.

+5
source

I want to share my decision. It will work for all fields without changes. I optimized it for this publication and removed some error checking, logging, and thread safety.

 - (BOOL)saveChanges:(NSError **)outError { BOOL result = YES; @try { NSError *error = nil; if ([self hasChanges]) { // Get field editor NSResponder *responder = [[NSApp keyWindow] firstResponder]; NSText *editor = [[NSApp keyWindow] fieldEditor: NO forObject: nil]; id editingObject = [editor delegate]; BOOL isEditing = (responder == editor); NSRange range; NSInteger editedRow, editedColumn; // End editing to commit the last changes if (isEditing) { // Special case for tables if ([editingObject isKindOfClass: [NSTableView class]]) { editedRow = [editingObject editedRow]; editedColumn = [editingObject editedColumn]; } range = [editor selectedRange]; [[NSApp keyWindow] endEditingFor: nil]; } // The actual save operation if (![self save: &error]) { if (outError != nil) *outError = error; result = NO; } else { result = YES; } // Now restore the field editor, if any. if (isEditing) { [[NSApp keyWindow] makeFirstResponder: editingObject]; if ([editingObject isKindOfClass: [NSTableView class]]) [editingObject editColumn: editedColumn row: editedRow withEvent: nil select: NO]; [editor setSelectedRange: range]; } } } @catch (id exception) { result = NO; } return result; } 
+4
source

All Articles