Last active
February 9, 2017 18:31
-
-
Save swillits/949bf6cf812110c8db81a9caf9e936ea to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@implementation NSWindow (Additions) | |
typedef NS_ENUM(NSUInteger, AGEndTextEditingOption) { | |
AGEndTextEditingAndClearFirstResponder = 0, | |
AGEndTextEditingAndMaintainFirstResponder, | |
}; | |
//! Returns YES if the field editor voluntarily gives up first responder status. Also returns YES if nothing was being edited. | |
//! If the maintain option is used, the first responder is set to the field editor's text field. | |
//! Returns NO if the field didn't want to give up first responder, probably because of some validation issue. In this case, use ag_forcefullyEndTextEditing if needed. | |
- (BOOL)ag_endTextEditing:(AGEndTextEditingOption)option | |
{ | |
// The goal of this method, is that IF the there is a field editor editing text, | |
// then we want to nicely end the text editing. In the past I simply just called | |
// [window endEditingFor:nil] but that actually doesn't work if the field editor | |
// is for a secure text field. (Interesting!) So instead we have to do it the | |
// correct way, which first tries makeFirstResponder. | |
// First we have to determine if there is a field editor. If there is, then it | |
// would be the first responder, so look for it there. | |
// | |
// We only want to call makeFirstResponder: if we're actually editing text | |
// otherwise we'd be moving the first responder "unexpectedly" to the user. | |
NSResponder * firstResponder = self.firstResponder; | |
if ([firstResponder isKindOfClass:[NSText class]]) { | |
NSText * text = (NSText *)firstResponder; | |
if (text.isFieldEditor) { | |
// Must get the text's delegate *before* changing first responder, otherwise it could go to nil. | |
if ([text.delegate isKindOfClass:[NSResponder class]]) { | |
firstResponder = (NSResponder *)text.delegate; | |
} | |
// Try to resign nicely. YES if it worked. | |
// (note we set the first responder to window not nil, because nil has some side effect I can't recall at the moment!) | |
if ([self makeFirstResponder:self]) { | |
// Reselect the field as first responder | |
if (option == AGEndTextEditingAndMaintainFirstResponder) { | |
[self makeFirstResponder:firstResponder]; | |
} | |
return YES; | |
} | |
// Refused to give up first responder | |
return NO; | |
} | |
} | |
// No editing is being performed, so we ended it successfully. | |
return YES; | |
} | |
@end | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment