Pregunta

¿Hay alguna notificación que pueda escuchar y que me avise cuando se sube el volumen de un iPhone? arriba?

sé sobre el AVSystemController_SystemVolumeDidChangeNotification, pero es esencial que la notificación solo se active cuando se haya subido el volumen, no hacia arriba o hacia abajo.

En segundo lugar, ¿cómo puedo ocultar la vista translúcida que aparece cuando se presiona el botón para subir el volumen, mostrando el volumen del sistema? Cámara+ ha implementado esto.

¿Fue útil?

Solución

No existe una forma documentada de solucionarlo, pero puede utilizar esta solución alternativa.Regístrese para AVSystemController_SystemVolumeDidChangeNotification notificación y agregar un MPVolumeView lo que evitará que aparezca la vista del volumen del sistema.

MPVolumeView *volumeView = [[MPVolumeView alloc] initWithFrame:CGRectMake(-100, 0, 10, 0)];
[volumeView sizeToFit];
[self.view addSubview:volumeView];

Y no olvides iniciar una sesión de audio.

AudioSessionInitialize(NULL, NULL, NULL, NULL);
AudioSessionSetActive(true);

En este caso, el MPVolumeView está oculto para el usuario.

En cuanto a verificar si se presionó subir o bajar el volumen, simplemente tome el volumen de la aplicación actual

float volumeLevel = [[MPMusicPlayerController applicationMusicPlayer] volume];  

y compararlo con el nuevo volumen después de presionar el botón en la devolución de llamada de notificación

Si no quieres hacerlo solo, hay una clase sin cita previa disponible en github.

https://github.com/blladnar/RBVolumeButtons

Otros consejos

Si desea un evento, puede registrar un oyente en la propiedad "outputVolume":

- (void)viewWillAppear:(BOOL)animated {

    AVAudioSession* audioSession = [AVAudioSession sharedInstance];

    [audioSession setActive:YES error:nil];
    [audioSession addObserver:self
                    forKeyPath:@"outputVolume"
                       options:0
                       context:nil];
}

-(void) observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {

    if ([keyPath isEqual:@"outputVolume"]) {
        NSLog(@"volume changed!");
    }
}

Resolví este problema agregando mi propio objetivo/acción para UISlider colocado dentro MPVolumeView.Por lo tanto, es posible detectar eventos de cambio de volumen y determinar qué botón se presionó.Aquí está repositorio de github con la implementación de este enfoque.Funciona bien con iOS 7 y superior, sin advertencias de desuso ni rechazo por parte de Apple.

Para distinguir la acción del volumen: EN LUGAR DE (en observarValue guard)

temp != 0.5

USAR solo para subir el volumen

temp > 0.5

y solo detecta volumen bajo:

temp < 0.5 

Esta solución a continuación se imprimirá si se presiona subir o bajar el volumen.

import AVFoundation
import MediaPlayer

override func viewDidLoad() {
  super.viewDidLoad()
  let volumeView = MPVolumeView(frame: CGRect.zero)
  for subview in volumeView.subviews {
    if let button = subview as? UIButton {
      button.setImage(nil, for: .normal)
      button.isEnabled = false
      button.sizeToFit()
    }
  }
  UIApplication.shared.windows.first?.addSubview(volumeView)
  UIApplication.shared.windows.first?.sendSubview(toBack: volumeView)
}

override func viewWillAppear(_ animated: Bool) {
  super.viewWillAppear(animated)
  AVAudioSession.sharedInstance().addObserver(self, forKeyPath: "outputVolume", options: NSKeyValueObservingOptions.new, context: nil)
  do { try AVAudioSession.sharedInstance().setActive(true) }
  catch { debugPrint("\(error)") }   
}

override func viewDidDisappear(_ animated: Bool) {
  super.viewDidDisappear(animated)
  AVAudioSession.sharedInstance().removeObserver(self, forKeyPath: "outputVolume")
  do { try AVAudioSession.sharedInstance().setActive(false) } 
  catch { debugPrint("\(error)") }
}

override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
  guard let key = keyPath else { return }
  switch key {
    case "outputVolume":
      guard let dict = change, let temp = dict[NSKeyValueChangeKey.newKey] as? Float, temp != 0.5 else { return }
      let systemSlider = MPVolumeView().subviews.first { (aView) -> Bool in
        return NSStringFromClass(aView.classForCoder) == "MPVolumeSlider" ? true : false
      } as? UISlider
      systemSlider?.setValue(0.5, animated: false)
      guard systemSlider != nil else { return }
      debugPrint("Either volume button tapped.")
    default:
      break
  } 
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top