Não é possível editar o NSTextField no NSPopover, embora o comportamento editável esteja definido

Eu tenho um aplicativo, que abre popover com NSTextField . O campo de texto não é editável. O comportamento do campo de texto está definido como Editable . Ainda posso colar e copiar texto para este campo, mas não consigo editá-lo.

Alguém sabe, o que pode estar errado?

Não tenho certeza se você ainda precisa da resposta, mas pode haver outras pessoas ainda procurando. Eu encontrei uma solução em fóruns de desenvolvedores da Apple. Citando o autor original:

O principal problema é a maneira como os events de teclado funcionam. Embora o NSTextField (e todas as suas supervisualizações) recebam events de teclado, ele não faz nenhuma ação. Isso acontece porque a exibição em que o popover está acoplado está em uma janela que não pode se tornar uma janela-chave. Você não pode acessar a janela de qualquer maneira, pelo menos eu não podia. Portanto, a solução é replace o método canBecomeKeyWindow para cada NSWindow em nosso aplicativo usando uma categoria.

 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 

Isso faz com que o popover resposive totalmente. Se você precisar de outra janela que responda NÃO a canBecomeKeyWindow, você sempre poderá criar uma subclass.

Eu lutei com isso por um tempo também, até que percebi que era um bug.

No entanto, em vez de confiar em um estado isActive de uma visualização NSStatusItem, considero muito mais confiável usar a propriedade isShown do NSPopover que você implementou.

No meu código, eu tenho um NSPopover em um NSViewController:

  - (BOOL)canBecomeKeyWindow { if([self class]==NSClassFromString(@"NSStatusBarWindow")) { NSPopover *mainPopover = [[((AppDelegate*)[NSApp delegate]) mainViewController] mainPopover]; if(![mainPopover isShown]) return NO; } return YES; } 

A resposta de Balazs Toth funciona, mas se você estiver anexando o popover a NSStatusItem.view, o item de status não responderá, exigindo dois cliques para focar.

O que eu encontrei ao trabalhar com esta solução é que quando NSStatusItem não responde, você pode facilmente replace esse comportamento como este

 - (BOOL)canBecomeKeyWindow { if([self class]==NSClassFromString(@"NSStatusBarWindow")) { CBStatusBarView* view = [((CBAppDelegate*)[NSApp delegate]) statusItemView]; if(![view isActive]) return NO; } return YES; } 

Você verificará a class da janela, se ela corresponder ao NSStatusBarWindow , podemos verificar de alguma forma se o NSStatusItem está ativo. Se for, significa que temos que retornar YES, porque desta forma o NSPopover de NSStatusItem terá todos os events do teclado.

O que estou usando para verificar se o NSStatusItem foi clicado (ou está ativo) é que na minha visualização personalizada eu tenho um valor de bool que muda quando o usuário clica no NSStatusItem , o sistema verifica automaticamente “canBecomeKeyWindow” e quando ele faz isso retornará NO e depois que o usuário clicar nele (enquanto estiver retornando o NO ) ele irá alterar o valor do bool e retornar YES quando o sistema perguntar novamente (quando o NSPopover estiver sendo clicado para a edição do NSTextField ).

Sidenotes :

  • CBStatusBarView é minha exibição personalizada para NSStatusItem
  • CBAppDelegate é minha class de delegação de aplicativos

Se alguém ainda está procurando uma resposta para isso, estou trabalhando no Swift.

No momento em que você deseja que o campo permita a input de texto, usei myTextField.becomeFirstReponder()

Optar por sair; apenas use myTextField.resignFirstResponder()

Definitivamente um bug. Esse relatório de bug é exatamente o que eu estava tentando fazer. Até mesmo para criar o item de status e replace o mousdown.

Posso confirmar que a resposta de Balazs Toth funciona. Só me pergunto se isso pode atrapalhar a estrada.

Se alguém entender e a solução acima não resolver o problema para ele. O problema no meu aplicativo estava na guia ” info nos targets meu aplicativo estava definido

 Application is background only = true 

e shulde de sido

  Application is agent = true 

Passei um dia inteiro nessa coisa.

insira a descrição da imagem aqui