问题
I want to change the device volume on iOS (iphone).
I know that i can change the volume of music library with this lines below:
//implement at first MediaPlayer framework
MPMusicPlayerController *musicPlayer = [MPMusicPlayerController iPodMusicPlayer];
musicPlayer.volume = 1;
But thats not my aim.
I want to change the device volume or let me say the volume of ringer.
How can i do that? just change the DEVICE volume?
回答1:
To answer brush51's question:
How can i do that? just change the DEVICE volume?
As 0x7fffffff suggested:
You cannot change device volume programatically, however MPVolumeView (volume slider) is there to change device volume but only through user interaction.
So, Apple recommends using MPVolumeView
, so I came up with this:
Add volumeSlider
property:
@property (nonatomic, strong) UISlider *volumeSlider;
Init MPVolumeView
and add somewhere to your view (can be hidden, without frame, or empty because of showsRouteButton = NO
and showsVolumeSlider = NO
):
MPVolumeView *volumeView = [MPVolumeView new];
volumeView.showsRouteButton = NO;
volumeView.showsVolumeSlider = NO;
[self.view addSubview:volumeView];
Find and save reference to UISlider
:
__weak __typeof(self)weakSelf = self;
[[volumeView subviews] enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
if ([obj isKindOfClass:[UISlider class]]) {
__strong __typeof(weakSelf)strongSelf = weakSelf;
strongSelf.volumeSlider = obj;
*stop = YES;
}
}];
Add target action for UIControlEventValueChanged
:
[self.volumeSlider addTarget:self action:@selector(handleVolumeChanged:) forControlEvents:UIControlEventValueChanged];
And then detect volume changing (i.e. by the hardware volume controls):
- (void)handleVolumeChanged:(id)sender
{
NSLog(@"%s - %f", __PRETTY_FUNCTION__, self.volumeSlider.value);
}
and also other way around, you can set volume by:
self.volumeSlider.value = < some value between 0.0f and 1.0f >;
Hope this helps (and that Apple doesn't remove MPVolumeSlider from MPVolumeView).
回答2:
Here's what I've done:
func setSystemVolume(volume: Float) {
let volumeView = MPVolumeView()
for view in volumeView.subviews {
if (NSStringFromClass(view.classForCoder) == "MPVolumeSlider") {
let slider = view as! UISlider
slider.setValue(volume, animated: false)
}
}
}
As property volume
in MPMusicPlayerController
was deprecate in iOS 7. This is only method you can do that.
回答3:
You have to use applicationMusicPlayer instead of iPodMusicPlayer to set the system volume:
#import <MediaPlayer/MediaPlayer.h>
musicPlayer = [MPMusicPlayerController applicationMusicPlayer];
musicPlayer.volume = 1; // max volume
musicPlayer.volume = 0; // min volume (mute)
musicPlayer.volume = 0.0625; // 1 bar on the overlay volume display
回答4:
This (Swift) solution worked great for me: http://weimenglee.blogspot.com/2015/07/ios-tip-programmatically-adjust-device.html
import MediaPlayer
let volumeView = MPVolumeView()
if let view = volumeView.subviews.first as? UISlider{
view.value = 0.1 //---0 t0 1.0---
}
回答5:
Here is a little wrapper class that can set the system volume and aslo notify you on any changes (pass your own change responder to setTarget:action:).
Edit: if you hide the MPVolumeView control or don't add it as a subview, then the system will show the default volume square in the middle of the screen whenever you change the volume programmatically. If you don't like what the system does, the solution is to set view coordinates outside of the screen. I edited my code below a bit to reflect this.
@import MediaPlayer;
@interface SysVolumeControl : MPVolumeView
@property (nonatomic) float value; // from 0 to 1.0
- (void)setTarget:(id)target action:(SEL)action;
@end
@implementation SysVolumeControl
{
UISlider* _slider;
}
- (id)init
{
if (self = [super initWithFrame:CGRectMake(-300, 0, 200, 50)])
{
for (UIView* view in self.subviews)
{
if ([view isKindOfClass:UISlider.class])
{
_slider = (UISlider*)view;
break;
}
}
}
return self;
}
- (float)value
{ return _slider.value; }
- (void)setValue:(float)value
{ _slider.value = value; }
- (void)setTarget:(id)target action:(SEL)action
{ [_slider addTarget:target action:action forControlEvents:UIControlEventValueChanged]; }
@end
Then create an instance and use it:
SysVolumeControl* sysVolumeControl = [SysVolumeControl new];
[myView addSubview:sysVolumeControl];
sysVolumeControl.value = 1.0;
[sysVolumeControl setTarget:self action:@selector(mySysVolumeResponder:)];
回答6:
Creating MPVolumeView on the fly to get the slider and set the volume doesn't work in iOS 11.4 anymore. I solved the issue by adding new MPVolumeView to my UIViewController view, otherwise it didn't set the volume. As I added it to the controller I also need to set the volume view position to be outside of the screen.
The code is in Swift 4:
let volumeControl = MPVolumeView(frame: CGRect(x: 0, y: 0, width: 120, height: 120))
override func viewDidLoad() {
self.view.addSubview(volumeControl);
}
override func viewDidLayoutSubviews() {
volumeControl.frame = CGRect(x: -120, y: -120, width: 100, height: 100);
}
func setMaxVolume() {
let lst = volumeControl.subviews.filter{NSStringFromClass($0.classForCoder) == "MPVolumeSlider"}
let slider = lst.first as? UISlider
slider?.setValue(1, animated: false)
}
回答7:
Swift 3 - I use this:
func setVolumeTo(volume: Float) {
(MPVolumeView().subviews.filter{NSStringFromClass($0.classForCoder) == "MPVolumeSlider"}.first as? UISlider)?.setValue(volume, animated: false)
}
回答8:
The app should not change device global settings and you should not do that. User can do that using standard iOS features.
Instead, if you playing a sound/video, then use player's volume
:
var player: AVPlayer!
...
player.volume = 0.5 // 50% level
来源:https://stackoverflow.com/questions/10286744/how-to-change-device-volume-on-ios-not-music-volume