是否有我可以收听的通知会告诉我何时打开 iPhone 的音量?
我知道AVSystemController_SystemVolumeDidChangeNotification
,但重要的是只有在音量调高而不是调高或调低时才会触发通知。
其次,如何隐藏按下音量增大按钮时出现的半透明视图,显示系统音量? Camera+已经实现了这一点。
是否有我可以收听的通知会告诉我何时打开 iPhone 的音量?
我知道AVSystemController_SystemVolumeDidChangeNotification
,但重要的是只有在音量调高而不是调高或调低时才会触发通知。
其次,如何隐藏按下音量增大按钮时出现的半透明视图,显示系统音量? Camera+已经实现了这一点。
如果你想要一个事件,你可以在“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!");
}
}
没有记录的方法可以解决此问题,但您可以使用此解决方法。注册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上有一个drop-in class
我通过为放置在里面的 UISlider 添加自己的目标/动作来解决这个问题MPVolumeView
。因此可以捕获音量变化事件并确定按下了哪个按钮。这是实现这种方法的github repo 。它适用于 iOS 7 及更高版本,没有弃用警告,也没有被 Apple 拒绝。
为了区分音量动作: 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
}
}