iOS 音量键翻页实现
前言:
最近老是有用户反馈说希望在阅读器里面加上一个音量键翻页的功能,作为一名多年的书虫,实在是无法理解,产品也注意到了这个事情,故去研究了一下
稍微谷歌了一下便可以知道,苹果以前是支持的,暴露了相关的api,在版本更新过程中移除了,要想监听物理音量键的按压事件,只能通过监听手机音量的变化,
但是又有一个问题是音量变化会在手机屏幕上有系统音量变化UI,这个当时随意看了下,觉得无法去除,遂拒绝了产品的需求。。。
最近突然又看到了类似的问题,且有用户提供了另外一款APP实现了该功能,遂深入了解下,话不多说,开始
1、获取音量监听
[kNotificationCenter addObserver:self selector:@selector(voliceChangeAction:) name:@"AVSystemController_SystemVolumeDidChangeNotification" object:nil]; [[UIApplication sharedApplication] beginReceivingRemoteControlEvents];
- (void)voliceChangeAction:(NSNotification *)sender { NSDictionary *dict = sender.userInfo; double voiceNum = [[dict objectOrNilForKey:@"AVSystemController_AudioVolumeNotificationParameter"] doubleValue]; if (voiceNum > cashVoice) { NSLog(@"音量加"); } if (voiceNum < cashVoice) { NSLog(@"音量减"); } }
2、隐藏系统音量变化UI
此处有一点需要注意,系统音量变化的UI有两种情况,要分开处理
一是铃声音量变化;
二是媒体音量变化;
导入 #import <AVFoundation/AVFoundation.h>
AVAudioSession *audioSession = [AVAudioSession sharedInstance]; NSError *error = nil; if (audioSession.otherAudioPlaying) { [audioSession setActive:NO error:&error]; } else { [audioSession setActive:YES error:&error]; }
导入 MediaPlayer
#import <MediaPlayer/MPVolumeView.h>
在当前控制器视图上添加一个不在屏幕 内的 MPVolumeView 对象即可隐藏掉 系统媒体音量变化UI
MPVolumeView *volieView = [[MPVolumeView alloc] initWithFrame:CGRectMake(-10, -100, 100, 100)]; [vc.view addSubview:volieView];
3、每次按完音量键之后需要重置音量,还是需要用到 MPVolumeView
UISlider *volumeViewSlider = nil; for (UIView *view in [volieView subviews]) { if ([view.class.description isEqualToString:@"MPVolumeSlider"]) { volumeViewSlider = (UISlider *)view; break; } } self.volumeViewSlider = volumeViewSlider; [self.volumeViewSlider setValue:0.25f animated:NO];
写的有点乱,不过主体代码都在这里了,稍微整理下进阅读器就可以实现这个功能
#import <MediaPlayer/MPVolumeView.h> #import <AVFoundation/AVFoundation.h> @property (nonatomic, strong) UISlider *volumeViewSlider; //监听 [kNotificationCenter addObserver:self selector:@selector(voliceChangeAction:) name:@"AVSystemController_SystemVolumeDidChangeNotification" object:nil]; [[UIApplication sharedApplication] beginReceivingRemoteControlEvents]; AVAudioSession *audioSession = [AVAudioSession sharedInstance]; NSError *error = nil; if (audioSession.otherAudioPlaying) { [audioSession setActive:NO error:&error]; } else { [audioSession setActive:YES error:&error]; } - (void)voliceChangeAction:(NSNotification *)sender { static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ UIViewController *vc = [self getCurrentActivityViewController]; MPVolumeView *volieView = [[MPVolumeView alloc] initWithFrame:CGRectMake(-10, -100, 100, 100)]; [vc.view addSubview:volieView]; UISlider *volumeViewSlider = nil; for (UIView *view in [volieView subviews]) { if ([view.class.description isEqualToString:@"MPVolumeSlider"]) { volumeViewSlider = (UISlider *)view; break; } } self.volumeViewSlider = volumeViewSlider; [self.volumeViewSlider setValue:0.25f animated:NO]; [kUserDefaults setDouble:0.25f forKey:@"reader_VoiceNum"]; }); NSDictionary *dict = sender.userInfo; double voiceNum = [[dict objectOrNilForKey:@"AVSystemController_AudioVolumeNotificationParameter"] doubleValue]; double cashVoice = [kUserDefaults doubleForKey:@"reader_VoiceNum"]; if (voiceNum == 0.25f) { return; } if (voiceNum > cashVoice) { NSLog(@"音量加"); } if (voiceNum < cashVoice) { NSLog(@"音量减"); } [kUserDefaults setDouble:0.25f forKey:@"reader_VoiceNum"]; //调整回音量 [self.volumeViewSlider setValue:0.25f animated:NO]; }