Search code examples
iosswiftdelegatesswift-protocolsswift-extensions

Swift - Invoke Custom Delegate Method


I am using BMPlayer library and want to implement custom control, for which I have the following class which confirm to following protocol

@objc public protocol BMPlayerControlViewDelegate: class {
    func controlView(controlView: BMPlayerControlView, didChooseDefition index: Int)
    func controlView(controlView: BMPlayerControlView, didPressButton button: UIButton)
    func controlView(controlView: BMPlayerControlView, slider: UISlider, onSliderEvent event: UIControlEvents)
    @objc optional func controlView(controlView: BMPlayerControlView, didChangeVideoPlaybackRate rate: Float)
}

open class BMPlayerControlView: UIView {
    open weak var delegate: BMPlayerControlViewDelegate?
    open weak var player: BMPlayer?

    // Removed rest of the code for clarity

    open func onButtonPressed(_ button: UIButton) {
        autoFadeOutControlViewWithAnimation()
        if let type = ButtonType(rawValue: button.tag) {
            switch type {
            case .play, .replay:
                if playerLastState == .playedToTheEnd {
                    hidePlayToTheEndView()
                }
            default:
                break
            }
        }
        delegate?.controlView(controlView: self, didPressButton: button)
    }
}

I am extending BMPlayerControlView class to extend the control view using the following code.

class BMPlayerCustomControlStyle3: BMPlayerControlView {

}

class BMPlayerStyle3: BMPlayer {

    class override func storyBoardCustomControl() -> BMPlayerControlView? {
        return BMPlayerCustomControlStyle3()
    }
}

My question is, how do I invoke didPressButton delegate method? I don't want to overwrite onButtonPressed, I tried the following

extension BMPlayerCustomControlStyle3:BMPlayerControlViewDelegate {

    func controlView(controlView: BMPlayerControlView, didChooseDefition index: Int) {
        
    }

    func controlView(controlView: BMPlayerControlView, didPressButton button: UIButton) {
        print("Did Press Button Invoked")
    }

    func controlView(controlView: BMPlayerControlView, slider: UISlider, onSliderEvent event: UIControlEvents) {
        
    }
}

And this doesn't seem to work, what am I missing here?

Thanks.


Solution

  • If you want your BMPlayerControlView subclass to also act as the delegate object, you need to set the delegate property as well (and conform to the BMPlayerControlViewDelegate protocol as you are already doing).

    One way to do so is by overriding the delegate superclass property in your subclass:

    class BMPlayerCustomControlStyle3: BMPlayerControlView {
    
        override open weak var delegate: BMPlayerControlViewDelegate? {
            get { return self }
            set { /* fatalError("Delegate for internal use only!") */ }
        }
    }
    

    Of course, when using the delegate internally such as this, you won't allow it to be used by BMPlayerControlView clients at all. The overridden set above ensures you get an error if trying to do so.