Обнаружить кнопку громкости iPhone Up Нажмите? - PullRequest
12 голосов
/ 12 марта 2012

Есть ли уведомление, которое я могу прослушать, которое сообщит мне, когда громкость iPhone увеличится вверх ?

Я знаю о AVSystemController_SystemVolumeDidChangeNotification, но важно, чтобы уведомление запускалось только при увеличении громкости, а не при увеличении или уменьшении.

Во-вторых, как мне скрытьполупрозрачный вид, который появляется при нажатии кнопки увеличения громкости, показывающий громкость системы? Камера + это реализовала.

Ответы [ 4 ]

37 голосов
/ 24 марта 2014

Если вы хотите событие, вы можете зарегистрировать слушателя в свойстве 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!");
    }
}
17 голосов
/ 14 апреля 2012

Нет задокументированного пути к этому, но вы можете использовать этот обходной путь.Зарегистрируйтесь для получения уведомления AVSystemController_SystemVolumeDidChangeNotification и добавьте MPVolumeView, который предотвратит отображение системного тома.

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

И не забудьте запустить аудиосеанс

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

В этом случае MPVolumeView скрыто от пользователя.

Что касается проверки, нажата ли громкость вверх или вниз, просто возьмите громкость текущего приложения

float volumeLevel = [[MPMusicPlayerController applicationMusicPlayer] volume];  

и сравните еес новой громкостью после нажатия кнопки в обратном вызове уведомлений

Если вы не хотите делать это самостоятельно, в github есть доступный класс

https://github.com/blladnar/RBVolumeButtons

3 голосов
/ 05 июня 2015

Я решил эту проблему, добавив собственную цель / действие для UISlider, размещенного внутри MPVolumeView.Таким образом, можно отследить события изменения громкости и определить, какая кнопка была нажата.Вот GitHub репо с реализацией этого подхода.Он отлично работает с iOS 7 и выше, без предупреждений об устаревании и без отклонений от Apple.

1 голос
/ 06 октября 2017

Чтобы различить действие громкости: ВМЕСТО (в поле наблюдения значения)

temp != 0.5

ИСПОЛЬЗОВАНИЕ только для увеличения громкости

temp > 0.5

и обнаруживает только уменьшение громкости:

temp < 0.5 

Это решение, приведенное ниже, будет распечатываться при нажатии на увеличение или уменьшение громкости.

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
  } 
}
...