通过 AudioPlayer 上的委托方法更新 UIProgressView
Updating UIProgressView via delegate method on AudioPlayer
我正在尝试 . Here's CADisplayLink
's initialiation signature
这里是 MyAudioPlayer
class.
相关变量的总结
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
}
}
当我在 play()
方法中初始化 updater
时,编译器说:
Argument of #selector
refers to instance method
updateSlider(sender:)
that is no exposed to Objective-C.
很简单...在 func updateSlider(sender: AudioPlayer)
前面添加 objc
,像这样:
@objc func updateSlider(sender: AudioPlayer)
编译器错误消失一纳秒,然后我刚刚更新的行说:
@objc can only be used with members of classes, @objc protocols, and
concrete extensions of classes.
有a few answers covering this topic,但我还没找到合适的。
我尝试将 updateSlider
放在扩展中而不是协议部分,但我一直收到编译器的乒乓球要在前面添加 @objc
然后要删除它。
我也尝试使用 Timer
class 的实例而不是 CADisplayLink
class 来执行此操作,但我遇到了同样的问题。
感谢您的阅读。我欢迎你的建议。
可以这样修复:)
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)
}
Dan 在这个问题上帮助我完成了任务。我需要在协议声明前添加 @objc
,而不是仅在我的委托方法前添加 @objc
。
// First change
@objc protocol AudioPlayerDelegate: class {
@objc func updateSlider(sender: AudioPlayer)
}
再往下 AudioPlayer
class...
// 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
我正在尝试 CADisplayLink
's initialiation signature
这里是 MyAudioPlayer
class.
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
}
}
当我在 play()
方法中初始化 updater
时,编译器说:
Argument of
#selector
refers to instance methodupdateSlider(sender:)
that is no exposed to Objective-C.
很简单...在 func updateSlider(sender: AudioPlayer)
前面添加 objc
,像这样:
@objc func updateSlider(sender: AudioPlayer)
编译器错误消失一纳秒,然后我刚刚更新的行说:
@objc can only be used with members of classes, @objc protocols, and concrete extensions of classes.
有a few answers covering this topic,但我还没找到合适的。
我尝试将 updateSlider
放在扩展中而不是协议部分,但我一直收到编译器的乒乓球要在前面添加 @objc
然后要删除它。
我也尝试使用 Timer
class 的实例而不是 CADisplayLink
class 来执行此操作,但我遇到了同样的问题。
感谢您的阅读。我欢迎你的建议。
可以这样修复:)
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)
}
Dan 在这个问题上帮助我完成了任务。我需要在协议声明前添加 @objc
,而不是仅在我的委托方法前添加 @objc
。
// First change
@objc protocol AudioPlayerDelegate: class {
@objc func updateSlider(sender: AudioPlayer)
}
再往下 AudioPlayer
class...
// 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