Rileva il pulsante del volume dell'iPhone su Premere?
-
12-12-2019 - |
Domanda
C'è una notifica che posso ascoltare ciò che mi dirà quando il volume di un iPhone è girato Up ?
Conosco il AVSystemController_SystemVolumeDidChangeNotification
, ma è essenziale che la notifica venga attivata solo quando il volume è stato alzato, non su o giù.
In secondo luogo, come posso nascondere la vista traslucida che appare quando viene premuto il pulsante Volume UP, mostrando il volume del sistema? Fotocamera + ha implementato questo.
Soluzione
Non c'è modo documentato a questo, ma è possibile utilizzare questa soluzione alternativa.Registrati per la notifica AVSystemController_SystemVolumeDidChangeNotification
e aggiungere un MPVolumeView
che impedirà la visualizzazione del volume del sistema da mostrare.
MPVolumeView *volumeView = [[MPVolumeView alloc] initWithFrame:CGRectMake(-100, 0, 10, 0)];
[volumeView sizeToFit];
[self.view addSubview:volumeView];
.
e non dimenticare di avviare una sessione audio
AudioSessionInitialize(NULL, NULL, NULL, NULL);
AudioSessionSetActive(true);
.
In questo caso, il MPVolumeView
è nascosto dall'utente.
Per quanto riguarda il controllo se è stato premuto il volume verso l'alto o il basso, basta prendere il volume dell'applicazione corrente
float volumeLevel = [[MPMusicPlayerController applicationMusicPlayer] volume];
.
e confrontalo con un nuovo volume dopo che il pulsante è stato premuto in notifica callback
Se non vuoi farlo da solo, c'è una classe di drop-in disponibile in GitHub
Altri suggerimenti
Se vuoi un evento puoi registrare un ascoltatore sulla proprietà "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!");
}
}
. Ho risolto questo problema aggiungendo il proprio obiettivo / azione per Uisilider posto all'interno di MPVolumeView
.Quindi è possibile prendere gli eventi di modifica del volume e determinare quale pulsante è stato premuto il pulsante.Ecco github repo con l'implementazione di questo approccio.
Funziona bene con iOS 7 e sopra, nessun avvertimento di deprecazione e nessun rifiuto da Apple.
Per distinguere l'azione del volume: anziché (in Guardia Guardia)
.
temp != 0.5
Usa per solo il volume su
.
temp > 0.5
e solo rilevare il volume verso il basso:
.
temp < 0.5
Questa soluzione seguente verrà stampata se viene premuto il volume verso l'alto o il basso.
.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
}
}