继承需求案例(搜索框定制)
继承从代码复用的角度来说,特别好用,也特别容易被滥用和被错用。不恰当地使用继承导致的最大的一个缺陷特征就是高耦合。
在这里我要补充一点,耦合是一个特征,虽然大部分情况是缺陷的特征,但是当耦合成为需求的时候,耦合就不是缺陷了。
案例来自:casatwy & 跳出面向对象思想(一) 继承.
以下为自己对文章的理解。
import UIKit
var ScreenH: CGFloat {
return UIScreen.main.bounds.height
}
var ScreenW: CGFloat {
return UIScreen.main.bounds.width
}
/*
* 搜索关键词 逻辑分离
*/
@objc protocol SearchProtocol {
@objc func search(params: [String:Any])
}
// 请求完成回调
typealias CompleteHolder = (Bool) -> Void
// 首页VM
class HomeViewModel: SearchProtocol {
// 页面数据
var sourceArr = [Any]()
// 刷新UI回调
var refreshUI: CompleteHolder?
// 关键词搜素
func search(params: [String:Any]){
// 请求接口 searchHome?keyword=keyword
print("请求了首页数据")
// 更新数据
sourceArr = [Any]()
// 刷新UI
guard let holder = refreshUI else { return }
holder(true)
}
}
// 分类页面VM
class ClassifyViewModel: SearchProtocol {
// 页面数据
var sourceArr = [Any]()
// 刷新UI回调
var refreshUI: CompleteHolder?
// 关键词搜素
func search(params: [String:Any]) {
// 请求接口 searchClassify?keyword=keyword&sort=2
print("请求了分类页面数据")
// 更新数据
sourceArr = [Any]()
// 刷新UI
guard let holder = refreshUI else { return }
holder(true)
}
}
// 自定义搜索框 左右结构
class CustomSearchBar: UIView {
var backButton: UIButton!
var searchTextfield: UITextField!
weak var delegate : SearchProtocol?
override init(frame: CGRect) {
super.init(frame: frame)
backgroundColor = .lightGray
backButton = UIButton(frame: CGRect(x: 0, y: 0, width: 40, height: frame.size.height))
backButton.setTitle("返回", for: .normal)
backButton.titleLabel?.font = UIFont.systemFont(ofSize: 16)
backButton.setTitleColor(.blue, for: .normal)
addSubview(backButton)
let searchTextfieldX = backButton.frame.maxX + 10
searchTextfield = UITextField(frame: CGRect(x: searchTextfieldX, y: 0, width: frame.size.width-searchTextfieldX, height: frame.size.height))
searchTextfield.placeholder = "搜高清热剧"
searchTextfield.font = UIFont.systemFont(ofSize: 14)
searchTextfield.layer.borderColor = UIColor.blue.cgColor
searchTextfield.layer.masksToBounds = true
searchTextfield.layer.borderWidth = 1/UIScreen.main.scale
searchTextfield.layer.cornerRadius = 5
searchTextfield.leftView = UIView(frame: CGRect(x: 0, y: 0, width: 10, height: frame.size.height))
searchTextfield.leftViewMode = .always
addSubview(searchTextfield)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
// 自定义搜索框 上下结构
class CustomSearchBigBar: UIView {
var searchTextfield: UITextField!
var promptLabel: UILabel!
weak var delegate : SearchProtocol?
override init(frame: CGRect) {
super.init(frame: frame)
backgroundColor = .lightGray
searchTextfield = UITextField(frame: CGRect(x: 0, y: 0, width: frame.size.width, height: frame.size.height-20))
searchTextfield.placeholder = "搜高清热剧"
searchTextfield.font = UIFont.systemFont(ofSize: 14)
searchTextfield.layer.borderColor = UIColor.blue.cgColor
searchTextfield.layer.masksToBounds = true
searchTextfield.layer.borderWidth = 1/UIScreen.main.scale
searchTextfield.layer.cornerRadius = 5
searchTextfield.leftView = UIView(frame: CGRect(x: 0, y: 0, width: 10, height: frame.size.height))
searchTextfield.leftViewMode = .always
addSubview(searchTextfield)
promptLabel = UILabel(frame: CGRect(x: 0, y: searchTextfield.frame.maxY, width: searchTextfield.frame.size.width, height: 20))
promptLabel.font = UIFont.systemFont(ofSize: 12)
promptLabel.text = "我是提示信息"
addSubview(promptLabel)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
class HomeViewController: UIViewController {
var searctBar = CustomSearchBar(frame: CGRect(x: 10, y: 120, width: ScreenW-20, height: 30))
var searctBigBar = CustomSearchBigBar(frame: CGRect(x: 10, y: 200, width: ScreenW-20, height: 30+20))
var logic = HomeViewModel()
var logicB = ClassifyViewModel()
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .white
view.addSubview(searctBar)
view.addSubview(searctBigBar)
// 两种样式不同的UI 调用同一个搜索逻辑
searctBar.delegate = logicB
searctBar.delegate?.search(params: ["keyworld":"影视"])
// searctBigBar.delegate = logicB
// searctBigBar.delegate?.search(params: ["keyworld":"影视","sort":1])
// 也可根据需求改动 更换另外一个逻辑
searctBigBar.delegate = logic
searctBigBar.delegate?.search(params: ["keyworld":"影视","sort":1])
}
}