por personalizar home flotante control centro boton assistive aparece activar iphone objective-c

personalizar - no me aparece el centro de control iphone



programa de acceso a los botones de volumen del iPhone (5)

¿Hay alguna forma de suscribirse a los botones de volumen presionar eventos?


Bueno,

Así que vi sus soluciones y no sé exactamente si Apple va a rechazar o aceptar el uso de AVSystemController_SystemVolumeDidChangeNotification . Pero tengo un trabajo alrededor.

Utilice UISlider de MPVolumeView para registrarse para cualquier cambio en el volumen con el hardware de iPhone como este

MPVolumeView *volumeView = [[MPVolumeView alloc] initWithFrame:CGRectZero]; for (UIView *view in [volumeView subviews]) { if ([view.class.description isEqualToString:@"MPVolumeSlider"]){ self.volume_slider = (UISlider*)view; break; } } [volumeView sizeToFit]; #THIS IS THE MAIN LINE. ADD YOUR CALLBACK TARGET HERE [self.volume_slider addTarget:self action:@selector(volumeListener:) forControlEvents:UIControlEventValueChanged]; [self addSubview:volumeView]; [volumeView setAlpha:0.0f]; -(void)volumeListener:(NSNotification*)notification { #UPDATE YOUR UI ACCORDING OR DO WHATEVER YOU WANNA DO. #YOU CAN ALSO GET THE SOUND STEP VALUE HERE FROM NOTIFICATION. }

Avísame si esto ayuda a alguien.


La forma más fácil y funcionalmente completa de hacer esto que he encontrado al estudiar todas las fuentes mencionadas anteriormente y en otros hilos es: JPSVolumeButtonHandler (no estoy involucrado más que como usuario. ¡Pero muchas gracias a los responsables!)

EDITAR: La versión 1.0.2 viene con algunos cambios / mejoras significativas. Dejaré mi respuesta anterior para 1.0.1 debajo de la tapa.

Puse una clase contenedora de muestra que puede implementar como está, o usar para aprender el uso correcto de JPSVolumeButtonHandler en un repositorio separado de Github muy rápido aquí .

Así es como se debe usar el contenedor (lo agregaré al repositorio tan pronto como lo encuentre):

  1. La clase singleton tiene dos banderas: isInUse e isOn . isInUse está destinado a establecerse en algún tipo de configuración general de la aplicación y activar y desactivar el soporte de botón en general. Entonces, sin importar ningún otro valor en la clase, si esto es false nada sucederá cuando el usuario presiona un botón de volumen y la implementación se asegura tanto como sea posible para mantener las cosas limpias y no afectar el nivel de volumen del sistema innecesariamente. (Lea el problema mencionado en el archivo README para saber qué puede pasar, cuando se activa la compatibilidad de botones por primera vez). isOn está destinado a ser true exactamente durante el tiempo que se necesita el botón. Puede isInUse y desactivarlo sin tener en cuenta el valor presente de isInUse .

  2. En cualquier vista que inicie la acción que se supone que debe suceder cuando se presiona un botón de volumen, configure la acción de la siguiente manera:

    PhysicalButton.shared.action = {/ * hacer algo * /}

La acción tiene type () -> Void . Hasta que inicie la acción, nada se romperá. Simplemente nada sucederá Esta funcionalidad defensiva era importante para mí, ya que la vista que utiliza la compatibilidad con botones de volumen solo se crearía después de configurar el soporte de botones.

Para ver cosas en acción, puedes descargar la aplicación que estoy usando de manera muy rápida y gratuita. Las configuraciones manipulan "Soporte de botón físico" en general. La vista principal de Cronómetro es la que realmente activa el manejo de los botones al ingresar a la vista, y se apaga al salir de ella. Si encuentra la hora, también encontrará una nota importante en Configuración> Guía del usuario> Opción: Soporte de botones físicos:

En circunstancias excepcionales, es posible que la aplicación no tenga la oportunidad de desactivar correctamente el manejo del botón de volumen fuera de la vista del cronómetro ...

Agregaré la nota completa a GITHUB README.md. Siéntase libre de adaptarlo y reutilizarlo, si es relevante en su caso.

Las circunstancias en realidad no son tan excepcionales y no he descubierto por completo cuál es el problema. Cuando el usuario cancela la aplicación (o simplemente detiene su aplicación desde Xcode) mientras los botones de volumen están activados, es posible que la compatibilidad con los botones físicos no se elimine del sistema operativo. Por lo tanto, puede terminar con dos instancias de controlador interno, solo una de las cuales tiene control. Entonces, cada vez que toca un botón, se producen dos o más llamadas a la rutina de acción. Mi envoltorio tiene un código de guardián para evitar una invocación demasiado rápida del botón. Pero eso es solo una solución parcial. La solución debe ir al controlador subyacente, que lamentablemente aún tengo muy poco conocimiento para tratar de arreglar las cosas por mí mismo.

ANTIGUO, PARA 1.0.1:

En particular, mi interés estaba en una solución Swift. El código está en Objective-C. Para salvar a alguien de la investigación, esto es todo lo que hice usando Cocoapods (para tontos como yo):

  1. Agregue el pod ''JPSVolumeButtonHandler'' al archivo podfile
  2. Ejecute la pod install en la línea de comando
  3. Agregue #import <JPSVolumeButtonHandler.h> al archivo de encabezado de puente
  4. Configure las devoluciones de llamada para los botones de subir y bajar el volumen de la siguiente manera:

    let volumeButtonHandler = JPSVolumeButtonHandler( upBlock: { log.debug("Volume up button pressed...") // Do something when the volume up button is pressed... }, downBlock: { log.debug("Volume down button pressed...") // Do something else for volume down... })

Eso es. El resto es opcional.

En mi caso, quería habilitar la superposición de botones físicos con botones virtuales en pantalla solo para seleccionar vistas, mientras me aseguro de bloquear la menor cantidad posible de las funciones de los botones normales (para que el usuario pueda ejecutar música en segundo plano y ajustar su volumen en el resto de la aplicación está bien). Terminé con una clase en su mayoría singleton de la siguiente manera:

class OptionalButtonHandler { static var sharedInstance: OptionalButtonHandler? private var volumeButtonHandler: JPSVolumeButtonHandler? = nil private let action: () -> () var enabled: Bool { set { if !enabled && newValue { // Switching from disabled to enabled... assert(volumeButtonHandler == nil, "No leftover volume button handlers") volumeButtonHandler = JPSVolumeButtonHandler(upBlock: { log.debug("Volume up button pressed...") self.action() }, downBlock: { log.debug("Volume down button pressed...") self.action() }) } else if enabled && !newValue { log.debug("Disabling physical button...") // The other way around: Switching from enabled to disabled... volumeButtonHandler = nil } } get { return (volumeButtonHandler != nil) } } /// For one-time initialization of this otherwise singleton class. static func initSharedInstance(action: () -> ()) { sharedInstance = OptionalButtonHandler(action: action) } private init(action: () -> ()) { self.action = action } }

Aquí solo hay una acción común para los botones de volumen hacia arriba y hacia abajo. El initSharedInstance() era necesario, porque mi acción incluía referencias a un elemento de IU (una vista) que solo se configuraría en algún punto dependiente del usuario después del lanzamiento de la aplicación.

Una vez configurado así:

OptionalButtonHandler.initSharedInstance({ // ...some UI action })

Activar / desactivar selectivamente simplemente así:

OptionalButtonHandler.sharedInstance!.enabled = true // (false)

(Tenga en cuenta que mi lógica de código se asegura de que .enabled nunca se acceda antes de initSharedInstance() .

Estoy ejecutando Xcode 7.3 y iOS 9.3.2 en el dispositivo de prueba (¡requerido!).

Estoy ansioso por saber cómo se siente Apple por sobrecargar sus preciosos botones de volumen. Al menos mi aplicación se asegura de ser mínimamente invasiva y el uso del botón realmente tiene sentido. No es una aplicación de cámara, pero las aplicaciones comparables han usado botones de volumen físico antes (incluso menos).


Si está dispuesto a sumergirse en la API privada, tengo un parche para Wolf3d que agrega exactamente la funcionalidad que está buscando. Utiliza la clase privada AVSystemController y algunos métodos ocultos en UIApplication


Si solo quieres recibir las notificaciones, creo que es así:

Por favor corrígeme si estoy equivocado, pero no creo que esto use ninguna API interna.

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(volumeChanged:) name:@"AVSystemController_SystemVolumeDidChangeNotification" object:nil];

Los detalles de este evento están aquí: http://www.cocoadev.com/index.pl?AVSystemController

Las otras respuestas aquí parecen basarse en este truco: http://blog.stormyprods.com/2008/09/proper-usage-of-mpvolumeview-class.html que fue una solución para un error ahora corregido.

Pero estoy bastante seguro de que si todo lo que quiere hacer es OBTENER la notificación, y no SET el volumen del sistema, ¡simplemente puede usar el centro de notificaciones como con cualquier otro evento!

Tenga en cuenta: desde que Apple agregó la acción de subir volumen a la cámara, esta notificación no se publica mientras está visible un UIImagePickerController .


Después de los recientes rechazos de Apple

No uses esto Apple ahora usa algún parche que rechazaría su aplicación inmediatamente si usa cualquiera de las API privadas, aunque debe tener en cuenta que algunas aplicaciones en la App Store ya lo usan y siguen ahí.

La única forma de hacer esto ahora es tener un AVAudioPlayer preparado para jugar pero no para jugar ([player prepareToPlay]). Esto parece ocuparse de ajustar el volumen de la aplicación de acuerdo con los botones basculantes.

No hay otra forma publicada actualmente para manejar esto.

POR FAVOR, LEA LA NOTA ANTERIOR

Sí, use el MPVolumeView

MPVolumeView *volume = [[[MPVolumeView alloc] initWithFrame:CGRectMake(18.0, 340.0, 284.0, 23.0)] autorelease]; [[self view] addSubview:volume]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(volumeChanged:) name:@"AVSystemController_SystemVolumeDidChangeNotification" object:nil]; for (UIView *view in [volume subviews]){ if ([[[view class] description] isEqualToString:@"MPVolumeSlider"]) { volumeViewSlider = view; //volumeViewSlider is a UIView * object } } [volumeViewSlider _updateVolumeFromAVSystemController]; -(IBAction)volumeChanged:(id)sender{ [volumeViewSlider _updateVolumeFromAVSystemController]; }

Esto le dará un control deslizante (el mismo que se usa en el iPod) cuyo valor cambiará según el volumen del teléfono

Obtendrá una advertencia en tiempo de compilación de que la vista puede no responder a _updateVolumeFromAVSystemControl, pero simplemente ignórelo.