repetidamente que puedo pide pida para otro mis las hacer cómo contraseña como cambio cambie cambiar borran apple app aplicaciones actualizar objective-c cocoa statusbar nsmenu nsmenuitem

objective-c - que - para actualizar aplicaciones en iphone me pide contraseña de otro id de apple



¿Cómo actualiza Apple el menú del Aeropuerto mientras está abierto?(Cómo cambiar NSMenu cuando ya está abierto) (3)

(Si desea cambiar el diseño del menú, de forma similar a cómo el menú del aeropuerto muestra más información cuando haga clic en él, siga leyendo. Si desea hacer algo completamente diferente, entonces esta respuesta puede no ser tan relevante como usted me gustaría.)

La clave es -[NSMenuItem setAlternate:] . Por ejemplo, digamos que vamos a construir un NSMenu que tenga una acción Do something... en él. Codificaría eso como algo como:

NSMenu * m = [[NSMenu alloc] init]; NSMenuItem * doSomethingPrompt = [m addItemWithTitle:@"Do something..." action:@selector(doSomethingPrompt:) keyEquivalent:@"d"]; [doSomethingPrompt setTarget:self]; [doSomethingPrompt setKeyEquivalentModifierMask:NSShiftKeyMask]; NSMenuItem * doSomething = [m addItemWithTitle:@"Do something" action:@selector(doSomething:) keyEquivalent:@"d"]; [doSomething setTarget:self]; [doSomething setKeyEquivalentModifierMask:(NSShiftKeyMask | NSAlternateKeyMask)]; [doSomething setAlternate:YES]; //do something with m

Ahora, pensarías que eso crearía un menú con dos elementos: "Haz algo ..." y "Haz algo", y estarías en parte en lo cierto. Debido a que configuramos el segundo elemento de menú para que sea alternativo, y debido a que ambos elementos de menú tienen el mismo equivalente de clave (pero máscaras de modificador diferentes), entonces solo se mostrará el primero (es decir, el que por defecto es setAlternate:NO ). Luego, cuando tiene el menú abierto, si presiona la máscara modificadora que representa la segunda (es decir, la tecla de opción), el elemento del menú se transformará en tiempo real desde el primer elemento del menú hasta el segundo.

Esto, por ejemplo, es cómo funciona el menú de Apple. Si hace clic una vez en él, verá algunas opciones con elipsis después de ellos, como "Reiniciar ..." y "Cerrar ...". El HIG especifica que si hay una elipsis, significa que el sistema solicitará confirmación al usuario antes de ejecutar la acción. Sin embargo, si presiona la tecla de opción (con el menú todavía abierto), notará que cambian a "Reiniciar" y "Apagar". Las elipses desaparecen, lo que significa que si las selecciona con la tecla de opción presionada, se ejecutarán inmediatamente sin pedir confirmación al usuario.

La misma funcionalidad general es válida para los menús en elementos de estado. Puede hacer que la información expandida sea elementos "alternativos" a la información normal que solo aparece con la tecla de opción presionada. Una vez que comprenda el principio básico, en realidad es bastante fácil de implementar sin muchos trucos.

Tengo un elemento de la barra de estado que abre un NSMenu, y tengo un juego de delegados y está conectado correctamente ( -(void)menuNeedsUpdate:(NSMenu *)menu funciona bien). Dicho esto, ese método se configura para que se llame antes de que se muestre el menú, necesito escuchar eso y activar una solicitud asincrónica, luego actualizar el menú mientras está abierto, y no puedo entender cómo se supone que debe hacerse .

Gracias :)

EDITAR

Ok, ahora estoy aquí:

Cuando hace clic en el elemento de menú (en la barra de estado), se llama a un selector que ejecuta un NSTask. Utilizo el centro de notificaciones para escuchar cuándo termina esa tarea y escribo:

[[NSRunLoop currentRunLoop] performSelector:@selector(updateTheMenu:) target:self argument:statusBarMenu order:0 modes:[NSArray arrayWithObject:NSEventTrackingRunLoopMode]];

y tiene:

- (void)updateTheMenu:(NSMenu*)menu { NSMenuItem *mitm = [[NSMenuItem alloc] init]; [mitm setEnabled:NO]; [mitm setTitle:@"Bananas"]; [mitm setIndentationLevel:2]; [menu insertItem:mitm atIndex:2]; [mitm release]; }

Este método definitivamente se llama porque si hago clic fuera del menú e inmediatamente regreso a él, obtengo un menú actualizado con esta información. El problema es que no está actualizando, mientras que el menú está abierto.


El problema aquí es que necesita que se active su devolución de llamada incluso en el modo de seguimiento de menú.

Por ejemplo, - [NSTask waitUntilExit] "sondea el bucle de ejecución actual usando NSDefaultRunLoopMode hasta que la tarea finalice". Esto significa que no se ejecutará hasta después de que se cierre el menú. En ese momento, la programación de updateTheMenu para ejecutar en NSCommonRunLoopMode no ayuda; después de todo, no puede retroceder en el tiempo. Creo que los observadores NSNotificationCenter también solo se activan en NSDefaultRunLoopMode.

Si puede encontrar la forma de programar una devolución de llamada que se ejecute incluso en el modo de seguimiento de menú, está configurado; simplemente puede llamar a updateTheMenu directamente desde esa devolución de llamada.

- (void)updateTheMenu { static BOOL flip = NO; NSMenu *filemenu = [[[NSApp mainMenu] itemAtIndex:1] submenu]; if (flip) { [filemenu removeItemAtIndex:[filemenu numberOfItems] - 1]; } else { [filemenu addItemWithTitle:@"Now you see me" action:nil keyEquivalent:@""]; } flip = !flip; } - (void)applicationDidFinishLaunching:(NSNotification *)aNotification { NSTimer *timer = [NSTimer timerWithTimeInterval:0.5 target:self selector:@selector(updateTheMenu) userInfo:nil repeats:YES]; [[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes]; }

Ejecuta esto y mantén presionado el menú Archivo, y verás que el ítem del menú adicional aparece y desaparece cada medio segundo. Obviamente, "cada medio segundo" no es lo que estás buscando, y NSTimer no entiende "cuando mi tarea de fondo haya terminado". Pero puede haber algún mecanismo igualmente simple que puedas usar.

De lo contrario, puede compilarlo usted mismo a partir de una de las subclases de NSPort; por ejemplo, cree un NSMessagePort y haga que su NSTask lo escriba cuando esté listo.

El único caso en el que realmente va a necesitar programar explícitamente updateTheMenu como describió Rob Keniger anteriormente es si está tratando de llamarlo desde fuera del ciclo de ejecución. Por ejemplo, podría engendrar un hilo que desencadena un proceso hijo y llama a waitpid (que bloquea hasta que finalice el proceso), entonces ese hilo debería llamar a performSelector: target: argumento: order: modes: en lugar de llamar a updateTheMenu directamente.


El seguimiento del mouse de menú se realiza en un modo de ciclo de ejecución especial ( NSEventTrackingRunLoopMode ). Para modificar el menú, debe enviar un mensaje para que se procese en el modo de seguimiento de eventos. La forma más sencilla de hacerlo es utilizar este método de NSRunLoop :

[[NSRunLoop currentRunLoop] performSelector:@selector(updateTheMenu:) target:self argument:yourMenu order:0 modes:[NSArray arrayWithObject:NSEventTrackingRunLoopMode]]

También puede especificar el modo como NSRunLoopCommonModes y el mensaje se enviará durante cualquiera de los modos de ciclo de ejecución comunes, incluido NSEventTrackingRunLoopMode .

Su método de actualización haría algo como esto:

- (void)updateTheMenu:(NSMenu*)menu { [menu addItemWithTitle:@"Foobar" action:NULL keyEquivalent:@""]; [menu update]; }