Как проверить, что все токены действительны в NSTokenField
Apple удобно создала метод обратного вызова, который позволяет вам проверить, являются ли новые токены, добавляемые в NSTokenField, действительными:
- (NSArray *)tokenField:(NSTokenField *)tokenField shouldAddObjects:(NSArray *)newTokens atIndex:(NSUInteger)index
Я реализовал это, и оказалось, что он прекрасно работает, за исключением одного случая. Если пользователь начинает вводить токен, но еще не завершил ввод токена, и пользователь нажимает клавишу TAB, метод проверки не вызывается.
Это означает, что я могу гарантировать, что все введенные токены действительны, если только пользователь не определится, он может нажать Tab, чтобы обойти проверку.
Кто-нибудь знает, как правильно справиться с этой ситуацией?
2 ответа
Я попытался немного и обнаружил, что поле токена вызывает control:isValidObject: протокола NSControlTextEditingDelegate при нажатии клавиши Tab. Таким образом, вы можете реализовать метод делегата, такой как
- (BOOL)control:(NSControl *)control isValidObject:(id)object
{
NSLog(@"control:%@", control);
NSLog(@"object:%@", object);
return NO;
}
Параметр 'object' - это содержимое вашего неполного токена. Если метод возвращает NO, токен не будет вставлен в массив допустимых токенов.
Я также борюсь с этой проблемой и обнаружил, что использование control: isValidObject, как предлагает zonble, почти достигает решения, но трудно определить, возвращать ли NO или YES на основе параметра объекта. Насколько я могу судить, эта проблема ограничена только клавишей табуляции, поэтому я реализовал пару методов следующим образом;
Я понимаю, что это ужасно некрасиво, но это единственный способ заставить NSTokenField избежать создания токенов на вкладке, не затрагивая другие действия NSTextField NSTokenField (например, перемещение курсора в новую позицию и т. Д.).
- (BOOL)control:(NSControl *)control isValidObject:(id)object
{
if (self.performingTab) {
self.performingTab=NO;
return NO;
} else {
return YES;
}
}
- (BOOL)control:(NSControl *)control textView:(NSTextView *)fieldEditor
doCommandBySelector:(SEL)commandSelector
{
if (commandSelector==@selector(insertTab:)) {
self.performingTab=YES;
}
return NO;
}
Я пробовал немного другой подход и вместо этого следил за клавишей табуляции, меняя ее на клавишу возврата. Этот метод делегата сначала подтверждает, что это соответствующее поле токена, и проверяет селектор команд.)
Приносим свои извинения за то, что оставили этот ответ в Swift - надеюсь, допустимо, учитывая прошедшие 8,5 лет.
func control(_ control: NSControl, textView: NSTextView, doCommandBy commandSelector: Selector) -> Bool
{
if control == tokenField, // my interested token field
commandSelector == #selector(insertTab(_:))
{
textView.insertNewline(self)
return true
}
return false
}