我希望在iOS(iPhone)上更改设备音量。
我知道可以使用以下代码更改音乐库的音量:
//implement at first MediaPlayer framework
MPMusicPlayerController *musicPlayer = [MPMusicPlayerController iPodMusicPlayer];
musicPlayer.volume = 1;
但这不是我的目的。
我想改变设备音量,或者说更改铃声的音量。
我该怎么做?只是更改设备音量吗?
回答 brush51 的问题:
我该怎么做?只改变设备音量吗?
正如 0x7fffffff 建议的:
你无法通过编程方式更改设备音量,但是有 MPVolumeView(音量滑块)可用于更改设备音量,但仅限用户交互。
因此,苹果建议使用 MPVolumeView
,因此我得出以下内容:
添加 volumeSlider
属性:
@property (nonatomic, strong) UISlider *volumeSlider;
初始化 MPVolumeView
并将其添加到您的视图中(可以隐藏,无框架或空白,因为 showsRouteButton = NO
和 showsVolumeSlider = NO
):
MPVolumeView *volumeView = [MPVolumeView new];
volumeView.showsRouteButton = NO;
volumeView.showsVolumeSlider = NO;
[self.view addSubview:volumeView];
查找并保存对 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;
}
}];
为UIControlEventValueChanged
添加目标操作:
[self.volumeSlider addTarget:self action:@selector(handleVolumeChanged:) forControlEvents:UIControlEventValueChanged];
然后检测音量的变化(例如通过硬件音量控制):
- (void)handleVolumeChanged:(id)sender
{
NSLog(@"%s - %f", __PRETTY_FUNCTION__, self.volumeSlider.value);
}
并且反过来,您也可以通过以下方式设置音量:
self.volumeSlider.value = < some value between 0.0f and 1.0f >;
希望这可以帮到你(也希望苹果不会从MPVolumeView中移除MPVolumeSlider)。
对我来说,这个(Swift)解决方案非常有效: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---
}
以下是我所做的内容:
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)
}
}
}
自iOS 7起,MPMusicPlayerController
中的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
@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
SysVolumeControl* sysVolumeControl = [SysVolumeControl new];
[myView addSubview:sysVolumeControl];
sysVolumeControl.value = 1.0;
[sysVolumeControl setTarget:self action:@selector(mySysVolumeResponder:)];
在iOS 11.4中,动态创建MPVolumeView来获取滑块并设置音量不再有效。我通过将新的MPVolumeView添加到我的UIViewController视图中来解决这个问题,否则它无法设置音量。由于我将其添加到控制器中,因此还需要将音量视图位置设置为屏幕外。
代码使用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)
}
音量
属性:var player: AVPlayer!
...
player.volume = 0.5 // 50% level
viewDidLoad
中调用listenVolumeButton
,并将//
行替换为你想要执行的任何操作。private func listenVolumeButton() {
let audioSession = AVAudioSession.sharedInstance()
try? audioSession.setActive(true)
audioSession.addObserver(self,
forKeyPath: "outputVolume",
options: NSKeyValueObservingOptions.new,
context: nil)
hideVolumeView()
}
private func hideVolumeView() {
let volumeView = MPVolumeView(frame: CGRect.zero)
for subview in volumeView.subviews {
if let button = subview as? UIButton {
button.setImage(nil, for: .normal)
button.isEnabled = false
button.sizeToFit()
}
}
UIApplication.shared.windows.first?.addSubview(volumeView)
UIApplication.shared.windows.first?.sendSubviewToBack(volumeView)
}
override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey: Any]?, context: UnsafeMutableRawPointer?) {
switch keyPath {
case "outputVolume":
guard let systemSlider = MPVolumeView().subviews.first(where: { NSStringFromClass($0.classForCoder) == "MPVolumeSlider" }) as? UISlider else {
return
}
let avoidLimitsValue = max(min(AVAudioSession.sharedInstance().outputVolume, Float(0.9)), Float(0.1))
DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 0.01) {
systemSlider.setValue(avoidLimitsValue, animated: false)
}
// DO YOUR STUFF HERE
default:
break
}
}
Swift 3 - 我使用这个:
func setVolumeTo(volume: Float) {
(MPVolumeView().subviews.filter{NSStringFromClass($0.classForCoder) == "MPVolumeSlider"}.first as? UISlider)?.setValue(volume, animated: false)
}
volumeView.showsRouteButton = NO; volumeView.showsVolumeSlider = NO;
,则音量值不会被设置。应该保持默认为YES。 - nahung89