swift - 通过覆盖init从故事板初始化视图控制器

时间:2015-08-05 01:14:59

标签: swift uiviewcontroller storyboard init

我在故事板中定义了一个ViewController实例。我可以通过以下

初始化它
var myViewController = UIStoryboard(name: "Main", bundle: nil).instantiateViewControllerWithIdentifier("myViewControllerIdentifier") as! ViewController

有没有办法覆盖ViewController的init方法,以便我可以使用

初始化它
var myViewController = ViewController()

我尝试重写init

convenience init() {
    self = UIStoryboard(name: "Main", bundle: nil).instantiateViewControllerWithIdentifier("SearchTableViewController") as! SearchTableViewController
}

但编译器并不喜欢这样。有什么想法吗?

3 个答案:

答案 0 :(得分:29)

一个便利初始化器必须总是委托给同一个类的指定初始化器,并且指定的初始化器必须调用一个超类初始化器。

由于超类没有合适的初始化程序,因此类工厂方法可能会更好:

static func instantiate() -> SearchTableViewController
{
    return UIStoryboard(name: "Main", bundle: nil).instantiateViewControllerWithIdentifier("SearchTableViewController") as! SearchTableViewController
}

然后使用:

var myViewController = SearchTableViewController.instantiate()

答案 1 :(得分:15)

类工厂方法是现在的方法。这是一个协议,可用于快速向所有protocol StoryboardInstantiable { static var storyboardName: String { get } static var storyboardBundle: NSBundle? { get } static var storyboardIdentifier: String? { get } } ​ extension StoryboardInstantiable { static var storyboardBundle: NSBundle? { return nil } static var storyboardIdentifier: String? { return nil } static func makeFromStoryboard() -> Self { let storyboard = UIStoryboard(name: storyboardName, bundle: storyboardBundle) if let storyboardIdentifier = storyboardIdentifier { return storyboard.instantiateViewControllerWithIdentifier(storyboardIdentifier) as! Self } else { return storyboard.instantiateInitialViewController() as! Self } } } 添加extension MasterViewController: StoryboardInstantiable { static var storyboardName: String { return "Main" } static var storyboardIdentifier: String? { return "Master" } } 支持。

storyboardIdentifier

示例:

storyboardName

如果视图控制器是故事板中的初始视图控制器,则可以忽略StoryboardInstantiable

如果所有视图控制器都在同一个故事板中,您还可以覆盖 public List<TextBox> boxes = null; public Form1() { InitializeComponent(); boxes = new List<TextBox>() { textBox1, textBox2, textBox3, textBox4}; foreach (TextBox box in boxes) { } 扩展名下的{{1}}并返回名称。

答案 2 :(得分:0)

您可以尝试泛型。像这样:

func Tvc<T>(_ vcType: T.Type) -> T {
    let vc = (vcType as! UIViewController.Type).vc//限制或明确为 UIViewController.Type
    return vc as! T
}

extension UIViewController {
    fileprivate static var vc: UIViewController {
        let M = UIStoryboard.init(name: "V", bundle: Bundle.main)
        return M.instantiateViewController(withIdentifier: "\(self)")
    }
}

示例

let vc = Tvc(HLCases.self)
_vc.navigationController?.pushViewController(vc, animated: true)