13

iPhoneの音量が上がったときに聞こえる通知はありますか?

については知っていAVSystemController_SystemVolumeDidChangeNotificationますが、音量が上がったり下がったりするのではなく、音量が上がったときにのみ通知がトリガーされることが重要です。

次に、音量大ボタンを押したときに表示される半透明のビューを非表示にして、システムの音量を表示するにはどうすればよいですか? Camera+はこれを実装しています。

4

4 に答える 4

38

イベントが必要な場合は、「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!");
    }
}
于 2014-03-24T04:46:38.460 に答える
17

これを行うための文書化された方法はありませんが、この回避策を使用できます。通知に登録し、システムボリュームビューが表示されないようにするを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

于 2012-04-14T16:14:59.350 に答える
3

内に配置されたUISliderの独自のターゲット/アクションを追加することで、この問題を解決しましたMPVolumeView。そのため、音量変更イベントをキャッチして、どのボタンが押されたかを判断することができます。これが、このアプローチを実装したgithubリポジトリです。iOS 7以降で正常に動作し、非推奨の警告やAppleからの拒否はありません。

于 2015-06-05T12:40:18.977 に答える
1

ボリュームアクションを区別するために: INSTEAD OF(observeValueガード内)

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
  } 
}
于 2017-10-06T17:45:37.540 に答える