iOS 7:不推荐使用 MPMusicPlayerController 音量。现在如何更改设备音量?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/19218729/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-31 02:08:48  来源:igfitidea点击:

iOS 7: MPMusicPlayerController volume deprecated. How to change device volume now?

iosios7volumempmusicplayercontroller

提问by Maxim Kholyavkin

MPMusicPlayerController setVolume is deprecated since iOS 7

MPMusicPlayerController setVolume自 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.

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

回答by ambientlight

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:

直到最近,我一直认为只能使用私有 API才能以编程方式使用 MPVolumeView 更改音量。但我刚刚验证,改变 volumeSlider 的值和伪造滑块的 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];

(When slider receives touchUP event, it will invoke _commitVolumeChangemethod on itself, which will change the system volume)

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

回答by amergin

Until Apple sees fit to rescind this decision there are two remedies I have discovered:

在 Apple 认为合适撤销此决定之前,我发现了两种补救措施:

  • 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.
  • 继续使用 volume 属性,它仍然在 iOS 7.0.2 下工作
  • 使用 AVAudioSession.outputVolume 在您的应用程序唤醒时读取音量,并在音量低于(或高于)用户指定值时弹出包含 MPVolumeView 的警报。至少你的用户知道他们的闹钟(或其他什么)会安静地播放并且有机会调节音量。或者,您可以非常清楚地显示音量级别,这样他们就不会感到意外。

回答by Jon Vogel

Just do this:

只需这样做:

let masterVolumeSlider: MPVolumeView = MPVolumeView()

if let view = masterVolumeSlider.subviews.first as? UISlider{

    view.value = 1.0

}

回答by charles.cc.hsu

@Hurden, I wrote a Swift code to implement the MPVolumeSlider:

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

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)

func rangeOfString 扩展字符串可以在这里找到Swift: A pure Swift method forReturn Ranges of a String instance (Xcode 6 Beta 5)

And use this code to let the gesture and mpvolumeslider work together

并使用此代码让手势和 mpvolumeslider 一起工作

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

回答by Oak

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

回答by Markus

Apparently there isa way to change the system volume without displaying anything at all.

显然有一种方法来改变系统的音量,而完全不显示任何内容

And best of all it works on iOS 11.

最重要的是它适用于iOS 11

Here's how I've achieved it:

这是我实现它的方式:

1) Create two variables in desired ViewController

1) 在所需的 ViewController 中创建两个变量

let volumeView = MPVolumeView()
var slider: UISlider?

2) Add the code below into your viewDidLoad

2) 将下面的代码添加到您的 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

3)随时改变音量

slider?.value = 0.4

回答by Krtko

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

这个解决方案让人有点紧张,我认为官方 API 不存在有点奇怪,但这是我的 Swift 解决方案建立在环境光的帖子之上

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
}

回答by Vicky

let masterVolumeSlider  : MPVolumeView = MPVolumeView()

        if let view             = masterVolumeSlider.subviews.first as? UISlider{

        view.value              = fVolume!

        view.sendActionsForControlEvents(UIControlEvents.TouchUpInside)

        }