iOS 7:不推荐使用MPMusicPlayerController。 如何改变设备的音量?

自iOS 7以来, MPMusicPlayerController setVolume已被弃用

有没有其他的方法来改变系统音乐的音量? 最好没有用户交互。 它的重要特点是:从AppStore自动增加任何闹钟的音量。

为了准确回答你的问题:是的,有没有其他的方式来改变系统音量没有用户的交互。

直到最近,我曾经认为只有使用私有API才能以编程方式使用MPVolumeView更改卷。 但是我刚刚证实,改变volumeSlider的值和伪装slider的touchUP事件的作用:

MPVolumeView* volumeView = [[MPVolumeView alloc] init]; //find the volumeSlider UISlider* volumeViewSlider = nil; for (UIView *view in [volumeView subviews]){ if ([view.class.description isEqualToString:@"MPVolumeSlider"]){ volumeViewSlider = (UISlider*)view; break; } } [volumeViewSlider setValue:1.0f animated:YES]; [volumeViewSlider sendActionsForControlEvents:UIControlEventTouchUpInside]; 

(当滑块接收到touchUP事件时,会调用_commitVolumeChange方法,这会改变系统的音量)

直到苹果认为适合撤销这个决定,我发现有两种补救措施:

  • 继续使用音量属性,它仍然在iOS 7.0.2下工作
  • 使用AVAudioSession.outputVolume在应用程序唤醒时读取卷,如果卷低于(或高于)用户指定的值,则popup包含MPVolumeView的警报。 至less你的用户知道他们的警报(或其他)会安静地播放,并有机会调整音量。 或者,您可以非常清楚地显示音量级别,这样他们就不会感到惊讶。

只要这样做:

 let masterVolumeSlider: MPVolumeView = MPVolumeView() if let view = masterVolumeSlider.subviews.first as? UISlider{ view.value = 1.0 } 

@Hurden,我写了一个Swift代码来实现MPVolumeSlider:

 for view in mpVolumeView.subviews { let uiview: UIView = view as UIView //println("\(uiview.description)") if uiview.description.rangesOfString("MPVolumeSlider").first != nil { mpVolumeSilder = (uiview as UISlider) currentDeviceVolume = mpVolumeSilder!.value return } } 

在这里可以findfunc rangeOfString扩展stringSwift:一个纯粹的Swift方法,用于返回String实例的范围(Xcode 6 Beta 5)

并使用此代码让手势和mpvol滑块一起工作

 @IBAction func handlePan(recognizer: UIPanGestureRecognizer) { let translation = recognizer.translationInView(self.view) let dx = (translation.x-lastTranslationX) let volumeChanged = Float(dx / mpVolumeView.frame.width) currentDeviceVolume = currentDeviceVolume + Float(volumeChanged) if currentDeviceVolume > 1 { currentDeviceVolume = 1 } else if currentDeviceVolume < 0 { currentDeviceVolume = 0 } mpVolumeSilder!.value = currentDeviceVolume if recognizer.state == .Changed { lastTranslationX = translation.x } if recognizer.state == .Ended || recognizer.state == .Began { lastTranslationX = 0 } } 

Swift版本:

 // Outlet added in Storyboard (Add UIView then set class to MPVolumeView) @IBOutlet weak var mpVolumeView: MPVolumeView! // Get volume slider within MPVolumeView for subview in self.mpVolumeView.subviews { if (subview as UIView).description.rangeOfString("MPVolumeSlider") != nil { // Set volume let volumeSlider = subview as UISlider volumeSlider.value = 1 // Works with or without the following line: // volumeSlider.sendActionsForControlEvents(UIControlEvents.TouchUpInside) break } } 

这个解决scheme有点紧张,我认为它有点奇怪的官方API不存在,但这里是我的Swift解决schemebuild立的ambientlight的职位

 var _volumeView = MPVolumeView() var _volumeSlider : UISlider? = nil self.view.addSubview(_volumeView) _volumeView.hidden = true var i = 0 while i < _volumeView.subviews.count { if let _r = _volumeView.subviews[i] as? UISlider { _volumeSlider = _r break } ++i } 
 let masterVolumeSlider : MPVolumeView = MPVolumeView() if let view = masterVolumeSlider.subviews.first as? UISlider{ view.value = fVolume! view.sendActionsForControlEvents(UIControlEvents.TouchUpInside) } 

显然有一种方法来改变系统音量而不显示任何东西

最重要的是它可以在iOS 11上运行

以下是我如何实现它:

1)在所需的ViewController中创build两个variables

 let volumeView = MPVolumeView() var slider: UISlider? 

2)将下面的代码添加到您的viewDidLoad

 volumeView.alpha = 0.01 self.view.addSubview(volumeView) if let view = volumeView.subviews.first as? UISlider { slider = view } 

3)只要你需要改变自己

 slider?.value = 0.4