Swift 中针对自定义组件的面向协议编程

Protocol Oriented Programming in Swift for custom components

我有一个 UIViewControllerUIView(作为组件)。以下是该组件的代码。

class ProcessingProgressIndicator: UIView {

   var progressView: UIProgressView!

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

所以我在多个控制器中使用这个组件。因此,当我需要更改我在控制器中使用的进度值时。

 myProgressView.changeProgress(progress)

因此,为了使组件面向协议,我在下面添加到代码中。

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

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

所以从我的控制器,我调用方法如下

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

这就是我使其面向协议的方式。

所以我的问题是:这是正确的实施方式吗?

我需要传递progressView的对象,我可以去掉吗?

您所说的是使用委托协议。

This 是 Apple 文档,我可以说编辑得很好,他们在其中解释了所有关于协议的内容。全部阅读,但跳转到代表团 session 以准确了解您要查找的内容。

如果你的注意力是通过委托来实现(还有其他选择,比如在闭包参数中返回进度值),应该类似于:

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)
    }

    // ...
}

我假设您的自定义组件是 UIView 的子类,应该没有什么区别。

用法:

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
    }
}

请注意,如果 updateProgressValue 范围将进度值更新为 real-time,则 customComponentProgressDidStartUpdate 委托方法也应作为 real-time 执行。

此外,您可能需要查看 以进一步了解这里发生的事情。

希望对您有所帮助。

因此,为了使组件面向协议,我在下面添加到代码中。

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)

这就是我使其面向协议的方式。