15

我想更改 iOS (iphone) 上的设备音量。

我知道我可以通过以下几行更改音乐库的音量:

//implement at first MediaPlayer framework
MPMusicPlayerController *musicPlayer = [MPMusicPlayerController iPodMusicPlayer];
musicPlayer.volume = 1;

但这不是我的目标。
我想改变设备音量或让我说铃声的音量。

我怎样才能做到这一点?只是改变设备音量?

4

9 回答 9

19

回答brush51的问题:

我怎样才能做到这一点?只是改变设备音量?

正如 0x7fffffff 建议的那样:

您不能以编程方式更改设备音量,但是 MPVolumeView(音量滑块)可以更改设备音量,但只能通过用户交互。

所以,苹果推荐使用MPVolumeView,所以我想出了这个:

添加volumeSlider属性:

@property (nonatomic, strong) UISlider *volumeSlider;

初始化MPVolumeView并添加到您的视图的某个位置(可以隐藏,没有框架,或者因为showsRouteButton = NOand为空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 >;

希望这会有所帮助(并且 Apple 不会从 MPVolumeView 中删除 MPVolumeSlider)。

于 2014-03-02T16:02:32.793 回答
8

这是我所做的:

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)
        }
    }
}

由于属性volumeinMPMusicPlayerController在 iOS 7 中已弃用。这是您可以做到的唯一方法。

于 2015-07-27T09:17:32.373 回答
8

这个(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---

}
于 2016-03-04T23:13:12.323 回答
6

您必须使用 applicationMusicPlayer 而不是 iPodMusicPlayer 来设置系统音量:

#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
于 2012-09-23T12:38:16.883 回答
3

这是一个小包装类,可以设置系统音量并通知您任何更改(将您自己的更改响应程序传递给 setTarget:action:)。

编辑:如果您隐藏 MPVolumeView 控件或不将其添加为子视图,则系统将在您以编程方式更改音量时在屏幕中间显示默认音量方块。如果您不喜欢系统所做的事情,解决方案是在屏幕外设置视图坐标。我在下面编辑了我的代码以反映这一点。

@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:)];
于 2015-08-14T21:47:29.467 回答
1

该应用程序不应更改设备全局设置,您也不应这样做。用户可以使用标准 iOS 功能做到这一点。相反,如果您播放声音/视频,请使用播放器volume

var player: AVPlayer!
...
player.volume = 0.5 // 50% level
于 2019-05-13T21:40:25.530 回答
1

即时创建 MPVolumeView 以获取滑块并设置音量在 iOS 11.4 中不再起作用。我通过将新的 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)
}
于 2018-06-05T17:59:09.700 回答
0

打电话给listenVolumeButton您并用您想做的任何事情viewDidLoad替换该行。//

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
    }
}
于 2020-07-24T14:44:39.580 回答
0

斯威夫特 3 - 我用这个:

func setVolumeTo(volume: Float) {
  (MPVolumeView().subviews.filter{NSStringFromClass($0.classForCoder) == "MPVolumeSlider"}.first as? UISlider)?.setValue(volume, animated: false)
}
于 2017-05-27T12:01:27.350 回答