首页 > 解决方案 > 更新值时 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)
    }
}

这很好,但我面临的最后一个问题是,当我放开滑块时,它似乎很快将滑块值设置回设置新值之前的值,然后快速自行修复。请看下面的视觉效果:

在此处输入图像描述

再次澄清一下,我一放手它就会像那样口吃,而不是在我试图滑动的时候

标签: swiftuislider

解决方案


这看起来像是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
        }
    })
}

推荐阅读