有没有办法实例化 - 设置 - 推送使用这样的辅助方法,但同时避免向下转换?
func pushController(id: String, setup: (_ vc: UIViewController) -> ()) {
if let vc = storyboard?.instantiateViewController(withIdentifier: id) {
setup(vc)
navigationController?.pushViewController(vc, animated: true)
}
}
// usage
pushController(id: "Cars") { vc in
(vc as! CarsVC).brand = "BMW"
}
// ...want to avoid downcasting
vc.brand = "BMW"
答案 0 :(得分:2)
我认为你不能避免向下倾斜,但你可以减少痛苦:
func pushController<VC: UIViewController>(id: String, setup: (_ vc: VC) -> ()) {
if let vc = storyboard?.instantiateViewController(withIdentifier: id) as? VC {
setup(vc)
navigationController?.pushViewController(vc, animated: true)
}
}
// usage
pushController(id: "Cars") { (vc: CarsVC) in
vc.brand = "BMW"
}
未经测试,因此可能存在小问题。
编辑:我应该注意,当ID与错误的类型一起使用时,这会无声地失败。您可能需要在else
之后添加if
来处理此问题。
答案 1 :(得分:2)
我能想到的最优雅的解决方案是使用泛型,比如这个(游乐场) - 例如:
import UIKit
extension UIViewController {
func pushController<T:UIViewController> (id: String, setup: (_ vc: T) -> ()) {
if let vc = self.storyboard?.instantiateViewController(withIdentifier: id) as? T {
setup(vc)
self.navigationController?.pushViewController(vc, animated: true)
}
}
}
class ViewControllerA:UIViewController {}
class ViewControllerB:UIViewController {
var bValue:Int = 0
}
let vcA = ViewControllerA();
vcA.pushController(id: "B") {
(vc:ViewControllerB) in
vc.title = "view controller b"
vc.bValue = 42;
}
我更倾向于使用显式泛型类型调用pushController
,但不幸的是Swift 3不支持这个:
vcA.pushController<ViewControllerB>(id: "B") { // Error: cannot explicitly specialize a generic function
vc in
vc.title = "view controller b"
vc.bValue = 42;
}