Parth Adroja
Parth Adroja

Reputation: 13514

Protocol Oriented Programming in Swift for custom components

I have one UIViewController and UIView(As Component). Below is code for the component.

class ProcessingProgressIndicator: UIView {

   var progressView: UIProgressView!

   func changeProgress(_ progress: Float) {
      progressView.progress = progress
   }
}

So I use this component in multiple controllers. So when I need to change the value of progress I have used as below in my controller.

 myProgressView.changeProgress(progress)

So to make the component Protocol Oriented I added below to code.

protocol ProgressUpdateable {
    func updateWith(progressView: ProcessingProgressIndicator,progress: Float)
}

extension ProgressUpdateable {
    func updateWith(progressView: ProcessingProgressIndicator,progress: Float) {
        // Method gets called and can change progress
    }
}

So from my controller, I call method as below

updateWith(progressView: progressView,progress: progressData.progress)

This is how I made it protocol oriented.

So my question is that: Is it correct way of implementation?

I need to pass the object of progressView can I get rid of it?

Upvotes: 4

Views: 712

Answers (3)

Parth Adroja
Parth Adroja

Reputation: 13514

So to make the component Protocol Oriented I added below to code.

protocol ProgressUpdateable {
    func updateWith(progressView: ProcessingProgressIndicator,progress: Float)
}

extension ProgressUpdateable {
    func updateWith(progressView: ProcessingProgressIndicator,progress: Float) {
        // Method gets called and can change progress
    }
}
So from my controller, I call method as below

updateWith(progressView: progressView,progress: progressData.progress)

This is how I made it protocol oriented.

Upvotes: 4

Ahmad F
Ahmad F

Reputation: 31655

If your attention is to achieve it via delegation (there are other options, such as returning the progress value in a closure parameter), it should be similar to:

protocol CustomComponentDelegate {
    func customComponentProgressDidStartUpdate(component: UIView, progressValue: Float)
}

class CustomComponent: UIView {

    var delegate:CustomComponentDelegate?

    // ...

    func updateProgressValue(progress: Float) {
        progressView.progress = progress/100.0
        progressLabel.text = "\(Int(progress)) %"

        delegate?.customComponentProgressDidStartUpdate(component: self, progressValue: progressView.progress)
        // or you might want to send (progress/100.0) instead of (progressView.progress)
    }

    // ...
}

I assumed that your custom component is a subclass of UIView, it shouldn't make a difference.

Usage:

class ViewController: UIViewController, CustomComponentDelegate {
    //...

    // or it might be an IBOutlet
    var customComponent: CustomComponent?

    override func viewDidLoad() {
        super.viewDidLoad()

        //...

        customComponent?.delegate = self
    }

    func customComponentProgressDidStartUpdate(component: UIView, progressValue: Float) {
        // do whatever you want with the returned values
    }
}

Note that if updateProgressValue scope updating the progress value as a real-time, then customComponentProgressDidStartUpdate delegate method should be also executed as a real-time.

Also, you might want to check this question/answer for more understanding about what's going on here.

Hope this helped.

Upvotes: 0

pinedax
pinedax

Reputation: 9356

What you are talking about is using a Protocols for Delegation.

This is Apple documentation, very well edited I can say, where they explain all about Protocols. Read it all but jump to the Delegation session to see exactly what you are looking for.

Upvotes: 0

Related Questions