问题
MPMusicPlayerController setVolume is deprecated since iOS 7
Is there any other way to change system music volume? Preferably without user interaction. Its important feature: to increase volume automatically for any alarm clock from AppStore.
回答1:
To answer you question exactly: Yes there is other way to change system volume without user interaction.
Until recent times I used to think that changing volume using MPVolumeView programmatically is possible only using private API. But I have just verified, that changing the value of volumeSlider and faking slider's touchUP event works:
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];
(When slider receives touchUP event, it will invoke _commitVolumeChange
method on itself, which will change the system volume)
回答2:
Until Apple sees fit to rescind this decision there are two remedies I have discovered:
- Keep using the volume property, it is still working under iOS 7.0.2
- Use AVAudioSession.outputVolume to read the volume when your app wakes and pop up an alert containing an MPVolumeView if the volume is lower than (or higher than) a user specified value. At least your user knows that their alarm (or whatever) will play quietly and has the opportunity to adjust the volume. Alternately you could just display very clearly the volume level so they get no surprises.
回答3:
Just do this:
let masterVolumeSlider: MPVolumeView = MPVolumeView()
if let view = masterVolumeSlider.subviews.first as? UISlider{
view.value = 1.0
}
回答4:
@Hurden, I wrote a Swift code to implement the 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
}
}
The func rangeOfString extension String can be found here Swift: A pure Swift method for returning ranges of a String instance (Xcode 6 Beta 5)
And use this code to let the gesture and mpvolumeslider work together
@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
}
}
回答5:
Swift Version:
// 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
}
}
回答6:
Apparently there is a way to change the system volume without displaying anything at all.
And best of all it works on iOS 11.
Here's how I've achieved it:
1) Create two variables in desired ViewController
let volumeView = MPVolumeView()
var slider: UISlider?
2) Add the code below into your viewDidLoad
volumeView.alpha = 0.01
self.view.addSubview(volumeView)
if let view = volumeView.subviews.first as? UISlider {
slider = view
}
3) Change volue whenever you need
slider?.value = 0.4
回答7:
This solution makes a bit nervous and I think its a bit odd an official API doesn't exist but here is my Swift solution built off of ambientlight's post
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
}
回答8:
let masterVolumeSlider : MPVolumeView = MPVolumeView()
if let view = masterVolumeSlider.subviews.first as? UISlider{
view.value = fVolume!
view.sendActionsForControlEvents(UIControlEvents.TouchUpInside)
}
来源:https://stackoverflow.com/questions/19218729/ios-7-mpmusicplayercontroller-volume-deprecated-how-to-change-device-volume-no