【问题标题】:iOS 7: MPMusicPlayerController volume deprecated. How to change device volume now?iOS 7:不推荐使用 MPMusicPlayerController 音量。现在如何更改设备音量?
【发布时间】:2013-10-13 15:58:46
【问题描述】:

MPMusicPlayerController setVolume 为deprecated since iOS 7

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

【问题讨论】:

  • 我也依赖此功能,因为我的用户希望能够设置和保存我的应用打开的音量。从开发人员的控制中移除这似乎是一件奇怪的事情。
  • 有AVAudioPlayer:stackoverflow.com/questions/5222464/…。我的问题是它是否可以播放 iPod 库中的歌曲。
  • 同意,Apple 弃用了这些方法而没有提供适当的替代品,这很奇怪。
  • 我注意到在 iOS 8.3 中,我的应用程序中的 MPMusicPlayerController 音量滑块根本不显示。它在早期的 iO​​S 版本中显示。没有对应用程序进行任何更改。有人在他们的应用中遇到过这个问题吗?
  • @kzia 请为此问题创建单独的问题

标签: ios ios7 volume mpmusicplayercontroller


【解决方案1】:

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

直到最近,我一直认为只有使用 私有 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方法,改变系统音量)

【讨论】:

  • 对不起,如果我很愚蠢。我正在尝试将您的代码粘贴到我的 js 函数中。 Dreamweaver 向我抛出了一个红色的语法箭头。这是js代码还是别的什么?
  • @Garavani 这是一个objective-c代码。而且和js集成也不是那么简单。请在类似这样的教程中在线查找更多信息 - bignerdranch.com/blog/javascriptcore-example
  • 这段代码,如所写,将引入一个问题:存储到“volumeView”中的对象的潜在泄漏
  • 解决方法:Potential leak of an object stored into 'volumeView' 将 volumeView 移动到这样的属性中:@property (nonatomic, retain) MPVolumeView* volumeView; 然后从循环中以这种方式访问​​它:for (UIView *view in [self.volumeView subviews]){
  • @ambientlight 我知道它不直接使用私有 API,但伪装用户交互作为触发私有 API _commitVolumeChange 的解决方法对我来说似乎有点冒险。还是)感谢你的建议! :)
【解决方案2】:

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

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

【讨论】:

  • 只应使用第二个选项 >= iOS 7.0。谢谢! :)
  • 从 iOS 10 开始,您仍然可以使用 volume 属性!
【解决方案3】:

这样做:

let masterVolumeSlider: MPVolumeView = MPVolumeView()

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

    view.value = 1.0

}

【讨论】:

  • 还需要一个“导入媒体播放器”
  • masterVolumeSlider.alpha = 0.01; self.view.addSubview(masterVolumeSlider) 还允许我在不显示操作系统音量计的情况下减少它
  • 我最喜欢这个答案,因为它很优雅并且不需要使用内部类名。它似乎很可能在未来不会中断。
【解决方案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 扩展字符串可以在这里找到Swift: A pure Swift method for returning ranges 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
  }
}

【讨论】:

    【解决方案5】:

    Swift 版本:

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

    【讨论】:

      【解决方案6】:

      显然一种改变系统音量的方法根本不显示任何内容

      最棒的是它适用于 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
      

      【讨论】:

        【解决方案7】:

        这个解决方案有点紧张,我觉得官方 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
        }
        

        【讨论】:

          【解决方案8】:
          let masterVolumeSlider  : MPVolumeView = MPVolumeView()
          
                  if let view             = masterVolumeSlider.subviews.first as? UISlider{
          
                  view.value              = fVolume!
          
                  view.sendActionsForControlEvents(UIControlEvents.TouchUpInside)
          
                  }
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2012-05-04
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2023-04-11
            相关资源
            最近更新 更多