对Swift最大的吐槽就是不允许多重继承,通过extension扩展某一个类带来的问题是全局有效的,想要控制它的可见范围,就要针对不同的场景隔离出不同的framework,如此在无形中提高了复杂度;所以最近野蛮地在团队里规定,如果是针对某一个类进行的功能扩展,优先使用:protocol + extension的方式,下面以在UINavigationController添加返回按钮为例进行说明:
import UIKit
import SnapKit
protocol EnableNavigationGoBack where Self:UIViewController {
func enableNavigationGoBack()
func onNavigationGoBackViewClicked()
}
extension EnableNavigationGoBack where Self:UIViewController {
func enableNavigationGoBack() {
let goBackView = UIButton(type: UIButtonType.custom)
if #available(iOS 11, *) {
goBackView.snp.makeConstraints { (make) in
make.width.equalTo(13)
make.height.equalTo(21)
}
} else {
goBackView.frame = CGRect(x: 0, y: 0, width: 13, height: 21)
}
goBackView.setImage(UIImage.init(named: "go_back"), for: UIControlState.normal)
goBackView.setOnClickedListener { [unowned self] (_) in
self.onNavigationGoBackViewClicked()
} // 参见:https://www.jianshu.com/p/0b2d5a03cd33
self.navigationItem.leftBarButtonItem = UIBarButtonItem.init(customView: goBackView)
}
func onNavigationGoBackViewClicked() {
if let rootViewController = self.navigationController?.viewControllers.first {
if rootViewController.isEqual(self) {
self.navigationController?.dismiss(animated: true, completion: nil)
return
}
}
self.navigationController?.popViewController(animated: true)
}
}
class UserViewController: UIViewController, EnableNavigationGoBack {
override func viewDidLoad() {
super.viewDidLoad()
enableNavigationGoBack()
}
}