用于推送UIViewController的Helper方法

时间:2017-02-21 18:44:10

标签: ios swift

有没有办法实例化 - 设置 - 推送使用这样的辅助方法,但同时避免向下转换?

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"

2 个答案:

答案 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;
}