42

MPMusicPlayerController setVolume自 iOS 7 起已弃用

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

4

8 回答 8

51

要准确回答您的问题:是的,还有其他方法可以在没有用户交互的情况下更改系统音量。

直到最近,我一直认为只有使用私有 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];

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

于 2014-07-28T10:15:07.080 回答
13

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

  • 继续使用 volume 属性,在 iOS 7.0.2 下依然有效
  • 使用 AVAudioSession.outputVolume 在您的应用唤醒时读取音量,并在音量低于(或高于)用户指定值时弹出包含 MPVolumeView 的警报。至少您的用户知道他们的闹钟(或其他)会安静地播放并有机会调整音量。或者,您可以非常清楚地显示音量级别,这样他们就不会感到意外。
于 2013-10-23T07:26:19.530 回答
10

只需这样做:

let masterVolumeSlider: MPVolumeView = MPVolumeView()

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

    view.value = 1.0

}
于 2015-07-02T22:02:52.083 回答
4

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

func rangeOfString 扩展 String 可以在这里找到Swift: A pure Swift method for return range of a String instance (Xcode 6 Beta 5)

并使用此代码让手势和 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
  }
}
于 2015-02-15T01:14:32.830 回答
1

斯威夫特版本:

// 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
        }
    }
于 2015-02-16T20:16:22.873 回答
1

显然有一种方法可以改变系统音量而不显示任何内容

最重要的是它适用于iOS 11

这是我实现它的方法:

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

let volumeView = MPVolumeView()
var slider: UISlider?

2)将下面的代码添加到您的 viewDidLoad

volumeView.alpha = 0.01
self.view.addSubview(volumeView)

if let view = volumeView.subviews.first as? UISlider {
    slider = view
}

3) 随时更改音量

slider?.value = 0.4
于 2017-08-22T17:49:00.587 回答
0

这个解决方案有点紧张,我觉得官方 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
}
于 2015-09-17T01:48:58.223 回答
0
let masterVolumeSlider  : MPVolumeView = MPVolumeView()

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

        view.value              = fVolume!

        view.sendActionsForControlEvents(UIControlEvents.TouchUpInside)

        }
于 2016-01-20T08:23:40.730 回答