【问题标题】:Fade (animate) Volume using MPMediaPlayer Swift 4使用 MPMediaPlayer Swift 4 淡化(动画)音量
【发布时间】:2019-05-22 05:59:09
【问题描述】:

我正在使用 Xcode 10+、Swift 4 并针对 iOS 11.4+ 使用 MPMediaPlayer

我想以编程方式淡出播放器的音量(就像 Apple 在您退出音乐播放器时所做的那样)。 同样,我不想在它运行时看到任何东西(比如 VolumeView 显示)。

似乎所有程序化音量控制已被弃用。

我已经阅读了很多相关的帖子并创建了这个有几个问题的函数:

@objc func fadeVolume(){
    var sliderView = UISlider()
    //let volumeView = MPVolumeView(frame: CGRect.init(x: self.view.frame.maxX, y: self.view.frame.maxY, width: 0, height: 0))
    let volumeView = MPVolumeView(frame: .zero)
    volumeView.clipsToBounds = true
    volumeView.showsRouteButton = false
    //volumeView.isHidden = true
    volumeView.alpha = 0.001
    for subview in volumeView.subviews {
        if let slider = subview as? UISlider {
            sliderView = slider
            break
        }
    }
    self.view.addSubview(volumeView)
    volumeView.didMoveToSuperview()

    let current:Float = AVAudioSession.sharedInstance().outputVolume
    print("slider value: \(current)")
    DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 0.1) {
        UIView.animate(withDuration: 0.4, animations: {
            sliderView.setValue(0.0, animated: false)
        }, completion: { finished in
            // If either one of these is uncommented, the VolumeView will display.
            // However, without removing from superview, the VolumeView stays hidden even when I use the phone volume buttons.
            volumeView.removeFromSuperview()
            //volumeView.alpha = 1.0
        })
    }
}

第一个问题:VolumeView 显示在屏幕上。我尝试过使用不同的帧,并更改 alpha 等。就好像动画从未发生过,它直接进入完成块。

第二个问题:VolumeView 确实需要从超级视图中删除,否则即使我使用手机音量按钮,它也会保持隐藏状态。它应该只在执行这个函数的过程中被隐藏。

第三个问题:动画块什么都不做。音量会立即从起点变为 0 - 不会衰减。

第四个问题:我没有对此进行测试,但我的假设是当应用程序在后台时这将不起作用。因此,在退出应用程序时使用它来淡出音量的想法可能行不通。

知道如何在屏幕上不显示任何内容的情况下淡出音量吗? 答案不一定需要使用 MPVolumeView,但我需要它与 MPMediaPlayer 以及在退出 App 时一起使用。

编辑: 下面是我修改后的代码,它将使音量变小,但是当我的应用程序终止时能够做到这一点的问题仍然存在。我可以从 'appWillTerminate' 调用此代码,但它并没有完全运行,因为应用程序在它可以一直循环之前终止。

// Public in ViewController Class:
let volumeView = MPVolumeView()
var sliderView = UISlider()
var currentVolume:Float = 0

//This called by a notification:
    @objc func fadeVolume(){
        // A lot of other posts use these to hide the volume view however I only needed the alpha change
        //volumeView.clipsToBounds = true
        //volumeView.showsRouteButton = false
        //volumeView.isHidden = true
        //print("volume alpha \(volumeView.alpha)")
        volumeView.alpha = 0.001
        self.view.addSubview(volumeView)
        volumeView.didMoveToSuperview()
        if let view = volumeView.subviews.first as? UISlider {
            sliderView = view
        }
        print("slider value: \(sliderView.value)")
        currentVolume = sliderView.value
        changeVolumeSlowly()
    }
    @objc func changeVolumeSlowly(){
        sliderView.value = sliderView.value - 0.1
        print("\(sliderView.value)")
        if sliderView.value > 0 {
            DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) { [weak self] in
                self?.changeVolumeSlowly()
            }
        } else {
            myMP.pause()
            myMP.stop()
            //reset
            // Since the volumeView is 'global' to the app, if you do not change
            // it back to the previous volume and make it visible you won't see it unless you restart your app.
            //Unfortunately these cause the volume view to flash onscreen
            volumeView.alpha = 1.0
            sliderView.value = currentVolume
            volumeView.removeFromSuperview()
        }
    }

【问题讨论】:

    标签: ios swift mpmediaplayercontroller


    【解决方案1】:

    公开你的 UISlider 变量并使用这个函数来淡化音量。

    @objc func changeVolumeSlowly(){
        sliderView.value = sliderView.value - 0.1
        print("\(sliderView.value)")
        if sliderView.value > 0 {
            DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) { [weak self] in
                self?.changeVolumeSlowly()
            }
        }
    }
    

    【讨论】:

    • 我已经尝试了您的代码,发现如果我也将 volumeView 声明为 public 并更改一些操作的顺序,它将起作用。但是,我无法在 applicationWillTerminate (我的原始问题的一部分)期间让它工作。我已经编辑了我的帖子以反映迄今为止的变化。
    猜你喜欢
    • 1970-01-01
    • 2018-03-06
    • 2018-03-01
    • 1970-01-01
    • 2018-09-23
    • 2014-07-10
    • 1970-01-01
    • 2018-03-06
    • 1970-01-01
    相关资源
    最近更新 更多