为AVPlayer更新时,UISlider会跳转

时间:2019-03-08 08:17:19

标签: ios swift avplayer uislider

我尝试使用UISlider实现简单的播放器,以指示当前音频文件的时间。

enter image description here

在代码中,我添加了两个观察者:

    slider.rx.value.subscribe(onNext: { value in
        let totalTime = Float(CMTimeGetSeconds(self.player.currentItem!.duration))
        let seconds = value * totalTime
        let time = CMTime(seconds: Double(seconds), preferredTimescale: CMTimeScale(NSEC_PER_SEC))
        self.player.seek(to: time)
        }).disposed(by: bag)
    let interval = CMTime(seconds: 0.1, preferredTimescale: CMTimeScale(NSEC_PER_SEC))
    player.addPeriodicTimeObserver(forInterval: interval, queue: nil) { [weak self] time in
        self?.updateSlider(with: time)
    }

具有一个私有功能:

private func updateSlider(with time: CMTime) {
    let currentTime = CMTimeGetSeconds(time)
    var totalTime = CMTimeGetSeconds(player.currentItem!.duration)
    if totalTime.isNaN {
        totalTime = 0
    }
    startLabel.text = Int(currentTime).descriptiveDuration
    endLabel.text = Int(totalTime).descriptiveDuration
    slider.value = Float(currentTime / totalTime)
}

播放音频时,一切都很好,并且滑块已更新很多。当我尝试在播放音频时手动移动滑块时会出现问题,然后它会跳转。为什么?

更新:

我知道为什么会这样。因为我更新了两次:手动更新并从玩家观察者那里更新,但是如何防止这种行为呢?我不知道;)请帮忙。

1 个答案:

答案 0 :(得分:2)

解决此问题的一种简单方法是防止在触摸滑块时addPeriodicTimeObserver调用self?.updateSlider(with: time)

这可以通过UISlider的{​​{1}}属性来确定:

  

isTracking

     

一个布尔值,指示控件当前是否正在跟踪   触摸事件。

     

在跟踪触摸事件时,控件会设置   此属性的值为true。当跟踪结束或被取消时   出于任何原因,都会将此属性设置为false。

     

参考:https://developer.apple.com/documentation/uikit/uicontrol/1618210-istracking

这出现在所有isTracking元素中,您可以通过以下方式使用它们:

UIControl

通用示例:

player.addPeriodicTimeObserver(forInterval: interval, queue: nil) { [weak self] time in
    //check if slider is being touched/tracked
    guard self?.slider.isTracking == false else { return }

    //if slider is not being touched, then update the slider from here
    self?.updateSlider(with: time)
}

我敢肯定还有其他(更好)的方法,但是我在RxSwift中还没有做很多(还)。
我希望目前为止足够好。

相关问题