通过AudioPlayer上的委托方法更新UIProgressView

时间:2017-05-30 19:07:22

标签: ios swift timer avaudioplayer cadisplaylink

我试图use CADisplayLink to update a UIProgressView。这是CADisplayLink's initialiation signature

以下是MyAudioPlayer类的相关变量摘要。

protocol AudioPlayerDelegate: class {
    func updateSlider(sender: AudioPlayer)
}

class AudioPlayer: NSObject {
    // relevant vars
    var updater: CADisplayLink?
    weak var delegate: AudioPlayerDelegate?

    func play() {
        // some setup stuff

        updater = CADisplayLink(target: self, selector: #selector(delegate?.updateSlider(sender:)))

        // regular stuff to play an audio file
    }
}

当我在updater方法中初始化play()时,编译器说:

  

#selector的参数是指实例方法   updateSlider(sender:)没有暴露于Objective-C。

足够简单......在objc前添加func updateSlider(sender: AudioPlayer),如下所示:

@objc func updateSlider(sender: AudioPlayer)

编译器错误消失了一个纳秒,然后我刚刚更新的行说:

  

@objc只能用于类成员,@ objc协议和   类的具体扩展。

a few answers covering this topic,但我找不到有效的。

我尝试在扩展中而不是在协议部分中抛出updateSlider,但我一直想让编译器想要在前面添加@objc,然后想要删除它。

我还尝试使用Timer类的实例代替CADisplayLink类来执行此操作,但我遇到了同样的问题。

感谢您的阅读。我欢迎你的建议。

2 个答案:

答案 0 :(得分:0)

可以修复如此:)

func play() {
    // some setup stuff

    updater = CADisplayLink(target: self, selector: #selector(updateSlider(sender:)))

    // regular stuff to play an audio file
}

func updateSlider(sender: AudioPlayer) {
    delegate?.updateSlider(sender: sender)
}

答案 1 :(得分:0)

丹在这个问题上让我超越终点线。我不需要在我的委托方法前面添加@objc,而是需要在协议声明前添加@objc

// First change
@objc protocol AudioPlayerDelegate: class {
    @objc func updateSlider(sender: AudioPlayer)
}

继续AudioPlayer班级......

// Delegate declaration
weak var delegate: AudioPlayerDelegate?

// Second Change
if let delegate = delegate {
    updater = CADisplayLink(target: delegate, selector: #selector(AudioPlayerDelegate.updateSlider(sender:)))
    updater?.preferredFramesPerSecond = 30
    updater?.add(to: RunLoop.current, forMode: .commonModes)
}

最后,当使用updater时,使其无效并将其取消(很可能是用于停止AVAudioPlayer实例的任何方法。

    updater?.invalidate()
    updater = nil