- 用于通信
一个简单的例子: 比如你封装了一个View, 需要回调出去一个按钮事件
class TestView: UIView {
// 注意这里要使用weak标记
weak var delegate: TestViewProtocol?
fileprivate lazy var iEnterBtn: UIButton = {
let btn = UIButton()
btn.addTarget(self, action: #selector(enterAction), for: .touchUpInside)
return btn
}()
@objc func enterAction() {
// 执行代理
delegate?.didClickEnterButton()
}
}
protocol TestViewProtocol: AnyObject {
func didClickEnterButton()
}
实现
class TestController: UIViewController {
fileprivate lazy var iTestView: TestView = {
let view = TestView()
// 签代理
view.delegate = self
return view
}()
override func viewDidLoad() {
super.viewDidLoad()
view.addSubview(iTestView)
}
}
extension TestController: TestViewProtocol {
// 实现代理方法
func didClickEnterButton() {
print("触发点击事件")
}
}
- 高阶使用
第一个问题: 如何让多个对象能够实现同一个方法, 统一函数名称
方法1: 基类+子类继承
传统的实现方法, OC也适用
- 定义基类
- 子类继承自基类
- 重写父类的方法
class BaseView: UIView {
// 根据传入的模型更新数据
func updateView() { }
}
class TestView0: BaseView {
// 重写更细试图的方法
override func updateView() {
}
}
class TestView1: BaseView {
// 重写更细试图的方法
override func updateView() {
}
}
方法2: 在Swift中运用面向协议的思路
- 声明协议与协议方法
- 需要此方法的类实现协议方法
protocol ViewProtocol: AnyObject {
func updateView()
}
class TestView0: UIView {
}
// 把属于同一个协议的实现方法写一个扩展, 使代码结构清晰
extension TestView0: ViewProtocol {
func updateView() {
}
}
class TestView1: UIView {
}
extension TestView1: ViewProtocol {
func updateView() {
}
}
第二个问题: 每个View都有对应的数据模型有更新UI的方法传值到View内部, 并给View相关控件赋值
能不能做到更新UI的方法统一, 模型参数不同呢
使用Protocol的关联属性
协议声明
protocol ViewProtocol: AnyObject {
// 关联类型
associatedtype T
// 将关联的类型传入函数
func updateView(model: T)
}
第一个测试View 数据模型为: Model_0
// 示例模型0
struct Model_0 {
var name = ""
var cover = ""
}
// 第一个View数据模型是 Model_0
class TestView0: UIView {
// 指明 关联类型是Model_0
typealias T = Model_0
}
// 实现协议方法
extension TestView0: ViewProtocol {
func updateView(model: Model_0) {
// 给控件赋值
}
}
第二个测试View 数据模型为: Model_1
// 示例模型1
struct Model_1 {
var name = ""
var cover = ""
}
// 第二个View数据模型是 Model_1
class TestView1: UIView {
// 指明 关联类型是Model_1
typealias T = Model_1
}
// 实现协议方法
extension TestView1: ViewProtocol {
func updateView(model: Model_1) {
// 给控件赋值
}
}
调用
// 创建模型Model_0
let model_0 = Model_0(name: "小明", cover: "http://xxx.com/xxxx")
// 实例化View
let testView_0 = TestView0()
// View调用更新函数
testView_0.updateView(model: model_0)
// 创建模型 Model_1
let model_1 = Model_1(name: "小明", cover: "http://xxx.com/xxxx")
// 实例化View
let testView_1 = TestView1()
// View调用更新函数
testView_1.updateView(model: model_1)
第三个问题: 多个对象都必须执行一个相同的方法
方式一: 每个对象内都去写这个方法实现, 会出现大量冗余重复的代码
方式二: 使用协议扩展-添加默认协议方法的实现, 如下:
协议扩展-添加默认实现
- 声明协议
protocol ViewProtocol: AnyObject {
func defaultFunc()
}
- 扩展协议
extension ViewProtocol where Self: UIView {
func defaultFunc() {
// 比如: 每个类调用的时候要上报给后端一个信息
print("默认实现的方法")
}
}
测试的两个View:
// 遵守了协议, 但是不用实现协议方法
class TestView_0: UIView, ViewProtocol {}
class TestView_1: UIView, ViewProtocol {}
调用:
let testView_0 = TestView0()
// 调用
testView_0.defaultFunc()
// 输出: 默认实现的方法
let testView_1 = TestView1()
// 调用
testView_1.defaultFunc()
// 输出: 默认实现的方法
网友评论