最近在看POP(Protocol-Oriental Programming)方向的文章, 碰巧有個需求適合用POP解決, 記錄一下.
需求是這樣的:
當(dāng)前控制器, 就叫CurrentViewController吧, 需要Push到一個另外的控制器選擇一個Staff對象, 就叫StaffViewController吧, StaffViewController里會根據(jù)Staff所在的部門, 層級不同, 選擇的時候會push到不同的下一級控制器, 這些下一級控制器里裝著不同的Staff或者其他部門, 選擇其他部門又會不一樣的操作, 我需要這些不同的控制器在完成選擇Staff對象的時候都直接pop回CurrentViewController里.
我的協(xié)議是這樣設(shè)計(jì)的:
protocol StaffSelectable {
}
extension StaffSelectable where Self: MyBaseViewController {
func actionAfterSelectStaff(staff: ContactStaff, ifNotForSelectStaff: @escaping () -> Void) {
if isDuringStaffSelection {
// 進(jìn)行選擇后的操作
// 跳轉(zhuǎn)回CurrentViewController
self.popToCurrentViewController()
} else {
ifNotForSelectStaff()
}
}
private func popToCurrentViewController() {
for vc in self.navigationController?.viewControllers ?? [] {
if vc.isKind(of: CurrentViewController.self) {
self.navigationController?.popToViewController(vc, animated: true)
}
}
}
}
在遵守這個協(xié)議的控制器種調(diào)用的代碼:
class SomeBaseViewController: MyBaseViewController, StaffSelectable {
private func didSelectStaff(vc: UIViewController, staff: Staff) {
self.actionAfterSelectStaff(staff: staff) {
// 提供這個控制器在不是選Staff的用途時的功能
self.navigationController?.pushViewController(someOtherViewController, animated: true)
}
}
}
這樣遵守這個協(xié)議的控制器在選完Staff的時候統(tǒng)一調(diào)這個方法就可以, 不用在基類定義方法, 更不用滿篇去CV代碼了??