前言:
最近老是有用戶反饋說希望在閱讀器里面加上一個音量鍵翻頁的功能,作為一名多年的書蟲,實在是無法理解,產品也注意到了這個事情,故去研究了一下
稍微谷歌了一下便可以知道,蘋果以前是支持的,暴露了相關的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]; }