2009-09-08 7 views
7

Tengo un NSMenu saliendo de un NSStatusItem usando popUpStatusItemMenu. Estos NSMenuItems muestran varios enlaces diferentes, y cada uno está conectado con setAction: con el método openLink: de un objetivo. Este arreglo ha estado funcionando bien durante mucho tiempo. El usuario elige un enlace del menú y el método openLink: luego se ocupa de él.Custom NSView en NSMenuItem que no recibe eventos de mouse

Lamentablemente, recientemente decidí experimentar con el uso del método setView: de NSMenuItem para proporcionar una interfaz más agradable/más elegante. Básicamente, dejé de configurar el título, creé NSMenuItem y luego utilicé setView: para mostrar una vista personalizada. Esto funciona perfectamente, los elementos del menú se ven muy bien y se muestra mi vista personalizada.

Sin embargo, cuando el usuario elige un elemento de menú y suelta el mouse, la acción ya no funciona (es decir, openLink: no se llama). Si simplemente comento el setView: call, entonces las acciones funcionan de nuevo (por supuesto, los elementos del menú están en blanco, pero la acción se ejecuta correctamente). Mi primera pregunta, entonces, es por qué configurar una vista rompe la acción del NSMenuItem.

No hay problema, pensé, lo solucionaré detectando el evento mouseUp en mi vista personalizada y llamando a mi método de acción desde allí. Agregué este método a mi vista personalizada:

- (void)mouseUp:(NSEvent *)theEvent { 
    NSLog(@"in mouseUp"); 
    } 

¡No dice! Este método nunca se llama.

Puedo establecer el seguimiento de las rectas y recibir mouseEntered: events, though. Puse algunas pruebas en mi rutina mouseEntered, de la siguiente manera:

if ([[self window] ignoresMouseEvents]) { NSLog(@"ignoring mouse events"); } 
else { NSLog(@"not ignoring mouse events"); } 
if ([[self window] canBecomeKeyWindow]) { dNSLog((@"canBecomeKeyWindow")); } 
else { NSLog(@"not canBecomeKeyWindow"); } 
if ([[self window] isKeyWindow]) { dNSLog((@"isKeyWindow")); } 
else { NSLog(@"not isKeyWindow"); } 

Y tiene las siguientes respuestas:

not ignoring mouse events 
canBecomeKeyWindow 
not isKeyWindow 

Es este el problema? "no esKeyWindow"? Presumiblemente, esto no es bueno porque los documentos de Apple dicen: "Si el usuario hace clic en una vista que no está en la ventana de clave, de forma predeterminada la ventana se adelanta y se convierte en clave, pero el evento del mouse no se envía". Pero debe haber una manera de detectar estos eventos. ¿CÓMO?

Adición:

[[self window] makeKeyWindow]; 

no tiene ningún efecto, a pesar del hecho de que canBecomeKeyWindow es SÍ.

+0

Hay más información sobre este problema en el radar abierta: http://openradar.appspot.com/7128269 También hay una solución reivindicada, pero no puede hacer el trabajo de solución. Básicamente, la ventana simplemente se niega a convertirse en clave, a pesar de que informa canBecomeKey. – Dennis

+0

Hola, me he enfrentado al mismo problema, ¿tienes algún progreso con él? He intentado algunas formas de solucionarlo, he encontrado una solución, pero es terriblemente fea, y después de mostrar el elemento de la barra de estado del menú no se resalta, pero el menú se muestra y es completamente funcional. Establecí el menú para el elemento de estado en cero y controlé manualmente el menú emergente. Si la aplicación está activa, solo llamo al método emergente de menú, si no envié un mensaje de aplicación activa, y en la devolución de llamada estoy abriendo el menú. Aquí hay un código. Otra vez es terrible y feo. http://gist.github.com/224275 – iafonov

+0

¡Tengo que decir que el código de iafonov es GENIAL! Aunque un año antes !!! Aunque el código parece irrelevante. ¡Gracias! Resuelve todos los problemas sobre NSVIew, NSTextEdit en NSMenuItem. Al principio, el NSTextEdit (en NSMenuItem) no funciona normalmente, no se puede presionar la tecla y el mouse no cambia. ¡Ahora todo funciona de maravilla! No acceptFirstResponder, No self window makeFirstResponder: xxx, Just iafonov'code. Es la forma de abrir el menú lo que importa. http://gist.github.com/224275 – user377808

Respuesta

9

añadir esto a la vista personalizada y que debe estar bien:

- (BOOL)acceptsFirstMouse:(NSEvent *)theEvent 
{ 
    return YES; 
} 
+1

¡Trabajado, gracias! – Vojto

4

añadí este método a mi vista personalizada, y ahora todo funciona muy bien:

- (void)viewDidMoveToWindow { 
    [[self window] becomeKeyWindow]; 
} 

Espero que esto ayude!

12

Añadir este método a su costumbre NSView y funcionará bien con los eventos del ratón

- (void)mouseUp:(NSEvent*) event { 
    NSMenuItem* mitem = [self enclosingMenuItem]; 
    NSMenu* m = [mitem menu]; 
    [m cancelTracking]; 
    [m performActionForItemAtIndex: [m indexOfItem: mitem]]; 
} 

pero estoy teniendo problemas con keyhandling, si usted ha resuelto este problema tal vez se puede ir a mi pregunta y me ayuden un poco.

+0

¡Esta fue la solución para mí! ¡Gracias! – kdbdallas

+0

Guau, me pasé medio día tratando de resolver esto. Gracias – Cory

-1

Recientemente tuve que mostrar una vista personalizada para un NSStatusItem, mostrar un NSMenu normal al hacer clic en él y admitir operaciones de arrastrar y soltar en el icono de estado.

Resolví mi problema utilizando, principalmente, tres fuentes diferentes que se pueden encontrar en la pregunta this.

Espero que ayude a otras personas.

-1

Vea el código de ejemplo de Apple llamado CustomMenus . Allí encontrará un buen ejemplo en la clase ImagePickerMenuItemView.

No es simple o trivial hacer que una vista en un menú actúe como un NSMenuItem normal. Hay algunas decisiones y códigos reales que hacer.

Cuestiones relacionadas