微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

更新值时 UISlider 卡顿

如何解决更新值时 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)
    }
}

这很棒,但我面临的最后一个问题是,当我松开滑块时,它似乎很快将滑块值设置回设置新值之前的值,然后快速修复自身。见下图:

enter image description here

再次澄清一下,它是这样的我一松开,而不是在我试图滑动时

解决方法

这看起来像 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 举报,一经查实,本站将立刻删除。