如何解决更新值时 UISlider 卡顿
我正在创建一个音频播放器并使用 UiSlider
实时更新音频的播放时间。我决定使用周期性时间观察者来做到这一点:
player.addPeriodicTimeObserver(forInterval: CMTime(seconds: 1,preferredTimescale: CMTimeScale(NSEC_PER_SEC)),queue: .main) { time in
slider.setValue(Float(time.seconds),animated: false)
}
这是一个好的开始,但是我遇到了一个问题,当我尝试使用滑块更改/寻找时间时会触发(可以理解),因此我将其更改为:
player.addPeriodicTimeObserver(forInterval: CMTime(seconds: 1,queue: .main) { time in
if !slider.isHighlighted {
slider.setValue(Float(time.seconds),animated: false)
}
}
这很棒,但我面临的最后一个问题是,当我松开滑块时,它似乎很快将滑块值设置回设置新值之前的值,然后快速修复自身。见下图:
再次澄清一下,它是这样的我一松开,而不是在我试图滑动时
解决方法
这看起来像 PeriodicTimeObserver
正在发送正确的值,但搜索实际上直到之后才完成,这导致了口吃。我建议你有一个标志,可以在要求观察者更新任何值之前确定搜索是否已完成。
我建议你做这样的事情,因为它不需要删除监听器而是忽略监听器。可能不是最好的解决方案,但它可以胜任。
var isSeeking = false
player.addPeriodicTimeObserver(forInterval: CMTime(seconds: 1,preferredTimescale: CMTimeScale(NSEC_PER_SEC)),queue: .main) { time in
if !isSeeking {
slider.setValue(Float(time.seconds),animated: false)
}
}
func seekToTime(_ time: CMTime) {
isSeeking = true
player.seek(to: time,completionHandler: { [unowned self] (completed) in
if completed {
isSeeking = false
resume()
}
})
}
,
尝试从滑块监听触摸事件。并删除/添加每个 - touchBegin/touchEnd 事件的观察者。这样您在手动更改时间时将不会收到来自播放器的更新。 查看有关如何保留观察令牌并在需要时将其删除的文档。 https://developer.apple.com/documentation/avfoundation/avplayer/1385829-addperiodictimeobserver 一些有用的 SO 链接 - In iOS AVPlayer,addPeriodicTimeObserverForInterval seems to be missing
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。