【问题标题】:UISlider stuttering when updating value更新值时 UISlider 口吃
【发布时间】:2021-07-19 05:17:14
【问题描述】:

我正在创建一个音频播放器并使用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)
    }
}

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

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

【问题讨论】:

  • 两个答案看起来都可能有所帮助,但都没有提到这一点:isContinuous。虽然它可能不是您想要的,但我想我应该向您指出这个属性。

标签: swift uislider


【解决方案1】:

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

【讨论】:

    【解决方案2】:

    尝试从滑块监听触摸事件。并在每个 - touchBegin/touchEnd 事件上删除/添加观察者。这样您在手动更改时间时将不会收到来自播放器的更新。 查看有关如何保留观察标记并在需要时将其删除的文档。 https://developer.apple.com/documentation/avfoundation/avplayer/1385829-addperiodictimeobserver 一些有用的 SO 链接 - In iOS AVPlayer, addPeriodicTimeObserverForInterval seems to be missing

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-11-04
      • 1970-01-01
      相关资源
      最近更新 更多