Невозможно редактировать NSTextField в NSPopover, даже если задано редактируемое поведение
У меня есть приложение, открывающее popover с NSTextField
. Текстовое поле не редактируется. Поведение для текстового поля установлено на Editable
. Я все еще могу вставить и скопировать текст в это поле, но я не могу его редактировать.
Кто-нибудь знает, что может быть неправильным?
Ответы
Ответ 1
Не уверен, что вам все еще нужен ответ, но могут быть некоторые другие, которые все еще ищут. Я нашел решение на форумах разработчиков Apple. Цитирование оригинального автора:
Основная проблема заключается в том, как работают клавиатурные события. Хотя NSTextField (и все его супервизоры) получает события клавиатуры, он не предпринимает никаких действий. Это происходит потому, что представление, в котором находится popover, находится в окне, которое не может стать ключевым окном. Вы никак не можете получить доступ к этому окну, по крайней мере, я не мог. Таким образом, решение переопределяет метод canBecomeKeyWindow для каждого NSWindow в нашем приложении с использованием категории.
NSWindow+canBecomeKeyWindow.h
@interface NSWindow (canBecomeKeyWindow)
@end
NSWindow+canBecomeKeyWindow.m
@implementation NSWindow (canBecomeKeyWindow)
//This is to fix a bug with 10.7 where an NSPopover with a text field cannot be edited if its parent window won't become key
//The pragma statements disable the corresponding warning for overriding an already-implemented method
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wobjc-protocol-method-implementation"
- (BOOL)canBecomeKeyWindow
{
return YES;
}
#pragma clang diagnostic pop
@end
Это делает popover полностью релевантным. Если вам нужно другое окно, которое должно отвечать NO на canBecomeKeyWindow, вы всегда можете сделать подкласс.
Ответ 2
Я тоже боролся с этим, пока не понял, что это ошибка.
Однако вместо того, чтобы полагаться на состояние isActive представления NSStatusItem, я считаю гораздо более надежным использовать свойство isShown реализованного вами NSPopover.
В моем коде у меня есть NSPopover в NSViewController:
- (BOOL)canBecomeKeyWindow
{
if([self class]==NSClassFromString(@"NSStatusBarWindow"))
{
NSPopover *mainPopover = [[((AppDelegate*)[NSApp delegate]) mainViewController] mainPopover];
if(![mainPopover isShown])
return NO;
}
return YES;
}
Ответ 3
Ответ Balazs Toth работает, но если вы прикрепляете popover к NSStatusItem.view, элемент состояния становится невосприимчивым - требуется два щелчка для фокусировки.
Ответ 4
То, что я нашел при работе с этим решением, заключается в том, что когда NSStatusItem перестает отвечать на запросы, вы можете легко переопределить это поведение, как это
- (BOOL)canBecomeKeyWindow {
if([self class]==NSClassFromString(@"NSStatusBarWindow")) {
CBStatusBarView* view = [((CBAppDelegate*)[NSApp delegate]) statusItemView];
if(![view isActive]) return NO;
}
return YES;
}
Вы проверите класс окна, если он соответствует NSStatusBarWindow, мы можем как-то проверить, активен ли NSStatusItem. Если это так, это значит, что мы должны вернуть ДА, потому что этот способ NSPopover из NSStatusItem будет иметь все события клавиатуры.
То, что я использую для проверки того, было ли нажато NSStatusItem нажато (или активно), - это то, что в моем собственном представлении у меня есть значение bool, которое изменяется, когда пользователь нажимает на NSStatusItem система автоматически проверяет "canBecomeKeyWindow", и когда она это сделает, она вернет NO и после того, как пользователь нажмет на нее (пока он возвращает NO), он изменит значение bool и вернет YES, когда система снова запросит (когда NSPopover нажимается для редактирования NSTextField).
Sidenotes
- CBStatusBarView - это мое пользовательское представление для NSStatusItem
- CBAppDelegate - класс моего делегата класса
Ответ 5
Если кто-то все еще ищет ответ на этот вопрос, я работаю в Swift.
В то время, когда вы хотите, чтобы поле разрешало ввод текста, я использовал myTextField.becomeFirstReponder()
Чтобы отказаться; просто используйте myTextField.resignFirstResponder()
Ответ 6
Определенно ошибка. Этот отчет об ошибках - это именно то, что я пытался сделать. Даже до создания элемента статуса и переопределения mousdown.
Я могу подтвердить, что ответ Балаза Тота работает. Я просто задаюсь вопросом, может ли это быть в пути по дороге.
Ответ 7
Если кто-то это получит, и вышеприведенное решение не сделает этого. Проблема в моем приложении была на вкладке " info
" в targets
к которым было применено мое приложение.
Application is background only = true
и был
Application is agent = true
Провел целый день на этой штуке.
![enter image description here]()
Ответ 8
Bug. http://openradar.appspot.com/9722231