在 iOS 8 上捕获音量增大/减小按钮的最简洁方法
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/28193626/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Cleanest way of capturing volume up/down button press on iOS 8
提问by Ricardo Sanchez-Saez
What's the best/cleanest way of capturing volume up/down button presses on iOS 8?
在iOS 8上捕获音量增大/减小按钮的最佳/最干净的方法是什么?
Ideally I'd like to capture the keypress and also prevent the system volume from changing (or at the very least, prevent the volume change HUD from showing).
理想情况下,我想捕获按键并防止系统音量发生变化(或者至少,防止音量变化 HUD 显示)。
There are some old answers going around which use deprecated methods and don't seem to work at all on iOS 8. This iOS 8 specific onedidn't work either.
有一些旧答案使用不推荐使用的方法,并且似乎在iOS 8 上根本不起作用。这个iOS 8 特定的也不起作用。
This RBVolumeButtonsopen source class doesn't seem to work on iOS 8 either.
这个RBVolumeButtons开源类似乎也不适用于 iOS 8。
回答by Mohammed Elrashidy
For Swift you can use next code in your viewController class:
对于 Swift,您可以在 viewController 类中使用下一个代码:
let volumeView = MPVolumeView(frame: CGRectMake(-CGFloat.max, 0.0, 0.0, 0.0))
self.view.addSubview(volumeView)
NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(volumeChanged(_:)), name: "AVSystemController_SystemVolumeDidChangeNotification", object: nil)
Then add this function
然后添加这个功能
func volumeChanged(notification: NSNotification) {
if let userInfo = notification.userInfo {
if let volumeChangeType = userInfo["AVSystemController_AudioVolumeChangeReasonNotificationParameter"] as? String {
if volumeChangeType == "ExplicitVolumeChange" {
// your code goes here
}
}
}
}
This code detect the explicit volume change action by the user, as if you didn't check of the explicit action, this function will be automatically called periodically.
此代码检测用户的显式音量更改操作,如果您没有检查显式操作,则会定期自动调用此函数。
This code don't prevent the system volume change
此代码不会阻止系统音量更改
回答by MFP
First add AVFoundationand MediaPlayerFrameworkand then you can use below code to detect up/down button press,
首先添加AVFoundation和MediaPlayer Framework,然后您可以使用以下代码检测向上/向下按钮按下,
-(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"]) {
float volumeLevel = [[MPMusicPlayerController applicationMusicPlayer] volume];
NSLog(@"volume changed! %f",volumeLevel);
}
}
回答by ingconti
for swift 3: (remember to add: import MediaPlayer.. )
对于 swift 3: (记得添加: import MediaPlayer.. )
override func viewDidLoad() {
super.viewDidLoad()
let volumeView = MPVolumeView(frame: CGRect(x: 0, y: 40, width: 300, height: 30))
self.view.addSubview(volumeView)
// volumeView.backgroundColor = UIColor.red
NotificationCenter.default.addObserver(self, selector: #selector(volumeChanged(notification:)),
name: NSNotification.Name(rawValue: "AVSystemController_SystemVolumeDidChangeNotification"),
object: nil)
}
func volumeChanged(notification: NSNotification) {
if let userInfo = notification.userInfo {
if let volumeChangeType = userInfo["AVSystemController_AudioVolumeChangeReasonNotificationParameter"] as? String {
if volumeChangeType == "ExplicitVolumeChange" {
// your code goes here
}
}
}
}
....
....
回答by Terry
Objective-C version (using notifications):
Objective-C 版本(使用通知):
#import <MediaPlayer/MPVolumeView.h>
#import <AVFoundation/AVFoundation.h>
@interface ViewController () {
UISlider *volumeViewSlider;
}
@end
@implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
[self startTrackingVolumeChanges];
}
- (void)dealloc
{
[self stopTrackingVolumeChanges];
}
#pragma mark - Start Tracking Volume Changes
- (void)startTrackingVolumeChanges
{
[self setupVolumeViewSlider];
[self addObserver];
[self activateAudioSession];
}
- (void)setupVolumeViewSlider
{
MPVolumeView *volumeView = [[MPVolumeView alloc] init];
for (UIView *view in [volumeView subviews]) {
if ([view.class.description isEqualToString:@"MPVolumeSlider"]) {
volumeViewSlider = (UISlider *)view;
break;
}
}
}
- (void)addObserver
{
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(volumeChanged:) name:@"AVSystemController_SystemVolumeDidChangeNotification" object:nil];
}
- (void)activateAudioSession
{
AVAudioSession *audioSession = [AVAudioSession sharedInstance];
[audioSession setCategory:AVAudioSessionCategoryPlayback withOptions:AVAudioSessionCategoryOptionMixWithOthers error:nil];
NSError *error;
BOOL success = [audioSession setActive:YES error:&error];
if (!success) {
NSLog(@"Error activating audiosession: %@", error);
}
}
#pragma mark - Observing Volume Changes
- (void)volumeChanged:(NSNotification *)notification
{
NSString *volumeChangeType = notification.userInfo[@"AVSystemController_AudioVolumeChangeReasonNotificationParameter"];
if ([volumeChangeType isEqualToString:@"ExplicitVolumeChange"]) {
float volume = volumeViewSlider.value;
NSLog(@"volume = %f", volume);
}
}
#pragma mark - Stop Tracking Volume Changes
- (void)stopTrackingVolumeChanges
{
[self removeObserver];
[self deactivateAudioSession];
volumeViewSlider = nil;
}
- (void)removeObserver
{
[[NSNotificationCenter defaultCenter] removeObserver:self name:@"AVSystemController_SystemVolumeDidChangeNotification" object:nil];
}
- (void)deactivateAudioSession
{
dispatch_async(dispatch_get_main_queue(), ^{
NSError *error;
BOOL success = [[AVAudioSession sharedInstance] setActive:NO error:&error];
if (!success) {
NSLog(@"Error deactivating audiosession: %@", error);
}
});
}
@end
回答by Gary Riches
Ah ok, see the Audio Session Services References for more information. You need to start an audio session with AudioSessionInitialize and then make it active with AudioSessionSetActive, listen for changes in the volume with AudioSessionAddPropertyListener and pass a callback that has type AudioSessionPropertyListener.
好的,请参阅音频会话服务参考以获取更多信息。您需要使用 AudioSessionInitialize 启动音频会话,然后使用 AudioSessionSetActive 使其处于活动状态,使用 AudioSessionAddPropertyListener 侦听音量变化并传递类型为 AudioSessionPropertyListener 的回调。
This web site has a good write up: http://fredandrandall.com/blog/2011/11/18/taking-control-of-the-volume-buttons-on-ios-like-camera/
这个网站写得很好:http: //fredandrandall.com/blog/2011/11/18/taking-control-of-the-volume-buttons-on-ios-like-camera/
回答by samwize
This is a 2 part answers, and they are independent, in Swift 5.
这是一个 2 部分的答案,它们在Swift 5 中是独立的。
To listen to the volume trigger event,
监听音量触发事件,
import MediaPlayer
// Observe in eg. viewDidLoad
let volumeChangedSystemName = NSNotification.Name(rawValue: "AVSystemController_SystemVolumeDidChangeNotification")
NotificationCenter.default.addObserver(self, selector: #selector(volumeChanged), name: volumeChangedSystemName, object: nil)
@objc private func volumeChanged(notification: NSNotification) {
guard
let info = notification.userInfo,
let reason = info["AVSystemController_AudioVolumeChangeReasonNotificationParameter"] as? String,
reason == "ExplicitVolumeChange" else { return }
// Handle it
}
To hide the system volume control,
要隐藏系统音量控制,
// Add the view but not visible
let volumeView = MPVolumeView(frame: CGRect(x: -CGFloat.greatestFiniteMagnitude, y: 0, width: 0, height: 0))
view.addSubview(volumeView)