swift - 更新值时 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, preferredTimescale: CMTimeScale(NSEC_PER_SEC)), 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
}
})
}
推荐阅读
- laravel - laravel 客户端 api 与 guzzle
- mysql - 排序规则将 utf8mb4_unicode_ci 更改为 utf8mb4_general_ci
- reactjs - 当上下文消费者中的任何状态发生变化时,React 是否会重新渲染所有组件?
- python - 如何解决“TypeError:不支持的格式字符串传递给 OSError.__format__”?
- python - 用另一个列表中的格式化文本替换列表中的文本
- python - Parser 必须是字符串或字符流,而不是 Series
- mongodb - 我如何将数据插入到 mongodb 的嵌入式集合中
- amazon-web-services - 有人可以为我揭开 AWS 服务中的 EMR/EC2/Lambda/SNS/SQ 的神秘面纱吗?
- ubuntu - --copt -DMESA_EGL_NO_X11_HEADERS --copt -DEGL_NO_X11 是什么意思?
- python - “AttributeError:‘numpy.ndarray’对象没有属性‘值’