我正在try 扩展:

extension UIViewController
{
    class func initialize(storyboardName: String, storyboardId: String) -> Self
    {
        let storyboad = UIStoryboard(name: storyboardName, bundle: nil)
        let controller = storyboad.instantiateViewControllerWithIdentifier(storyboardId) as! Self

        return controller
    }
}

但我发现编译错误:

错误:无法将"UIViewController"类型的返回表达式转换为

可能吗?而且我想让它成为init(storyboardName: String, storyboardId: String)

推荐答案

Similar as in Using 'self' in class extension functions in Swift, you can define a generic helper method which infers the type of self from the calling context:

extension UIViewController
{
    class func instantiateFromStoryboard(storyboardName: String, storyboardId: String) -> Self
    {
        return instantiateFromStoryboardHelper(storyboardName, storyboardId: storyboardId)
    }

    private class func instantiateFromStoryboardHelper<T>(storyboardName: String, storyboardId: String) -> T
    {
        let storyboard = UIStoryboard(name: storyboardName, bundle: nil)
        let controller = storyboard.instantiateViewControllerWithIdentifier(storyboardId) as! T
        return controller
    }
}

然后

let vc = MyViewController.instantiateFromStoryboard("name", storyboardId: "id")

编译,类型推断为MyViewController.


更新为Swift 3:

extension UIViewController
{
    class func instantiateFromStoryboard(storyboardName: String, storyboardId: String) -> Self
    {
        return instantiateFromStoryboardHelper(storyboardName: storyboardName, storyboardId: storyboardId)
    }

    private class func instantiateFromStoryboardHelper<T>(storyboardName: String, storyboardId: String) -> T
    {
        let storyboard = UIStoryboard(name: storyboardName, bundle: nil)
        let controller = storyboard.instantiateViewController(withIdentifier: storyboardId) as! T
        return controller
    }
}

另一种可能的解决方案是使用unsafeDowncast:

extension UIViewController
{
    class func instantiateFromStoryboard(storyboardName: String, storyboardId: String) -> Self
    {
        let storyboard = UIStoryboard(name: storyboardName, bundle: nil)
        let controller = storyboard.instantiateViewController(withIdentifier: storyboardId)
        return unsafeDowncast(controller, to: self)
    }
}

Swift相关问答推荐

SWIFT闭包使用的是陈旧的值,即使它是S@转义

在SwiftUI中绘制形状的路径后填充形状

在表单中对齐文本框

使第二个视图变灰 SwiftUI

如何在 swiftui 中设置给定字符串类型日期的日期倒计时?

NavigationStack 和 TabView - 工具栏和标题不显示

如何制作进度加载动画?

RxSwift 事件触发了两次

单击按钮后的计时器发布者初始化计时器

故事板未在助手中显示视图控制器

为什么 switch 在 optional 中不接受 case nil?

展开 List 中的 HStack 以端到端但不是从上到下,因此看起来项目之间有更宽的空间

调用从 SwiftUI 视图传递到 PageViewController.Coordinator 的函数

在 xcode 13 中的构建之间保持可访问性权限

SwiftUI 文本被意外截断

为什么 `map(foo)` 和 `map{ foo($0) }` 返回不同的结果?

Alamofire 会自动存储 cookie 吗?

如何从 Button 获取标签名称?

是 swift 中另一个日期的同一周、月、年的日期

Swift 中的可选数组与空数组