从Self返回UIViewController的类型

时间:2018-03-30 10:57:57

标签: ios swift uiviewcontroller

我想创建一个隐式返回一种ViewController的扩展。例如:

extension UIViewController{
    @nonobjc func initiateAndAddToContainerReturnVc(identifier: String, storyboard: String, container: UIView) -> UIViewController{
        let view = initiateViewControllerFromName(identifier, storyboard: storyboard)
        addChildViewController(view)
        view.addToContainer(container: container)
        return view
    }
}

因此,当我使用它时,我可以做这样的事情:

var myViewController: MyViewController!
var container: UIView!
override func viewDidLoad() {
    super.viewDidLoad()
    myViewController = MyViewController().initiateAndAddToContainerReturnVc(identifier: "myViewController", storyboard: "Main",container: container) as !MyViewController
}

func initiateViewControllerFromName(_ viewControllerName: String, storyboard: String) -> UIViewController {

    return UIStoryboard(name: storyboard, bundle: nil).instantiateViewController(withIdentifier: viewControllerName)
}

我要问的是,我是否可以将我的扩展名更改为隐含暗示ViewController是MyViewController类型的self而不是依赖于“as!MyViewController”

我很确定我可以做些什么,但我已经尝试阅读文档并搜索这个网站,但我仍然无法找到解决方案。

2 个答案:

答案 0 :(得分:1)

//在UIViewController扩展

中创建一个静态方法
    extension UIViewController {
        static func initiateAndAddToContainerReturnVc(identifier: String, storyboard: String, container: UIView) -> Self {
            let view = initiateViewControllerFromName(identifier: identifier, storyboard: storyboard,viewcontrollerClass:self)
            addChildViewController(view)
            view.addToContainer(container: container)
            return view
        }
    }

//在扩展名之外的某处定义initiateViewControllerFromName方法,并使其像下面一样通用。

    class func initiateViewControllerFromName<T:UIViewController>(identifier:String, storyboard: String,viewcontrollerClass: T.Type) -> T {
       return UIViewController() as! T  // Add viewcontroller instance code here and typecast it to 'T'
    }

答案 1 :(得分:0)

尝试引入泛型类型参数:

@nonobjc func initiateAndAddToContainerReturnVc<T: UIViewController>(identifier: String, storyboard: String, container: UIView) -> T{
    let view = initiateViewControllerFromName(identifier, storyboard: storyboard) as! T
    addChildViewController(view)
    view.addToContainer(container: container)
    return view
}

你可以像这样使用它:

settings = MyViewController().initiateAndAddToContainerReturnVc(identifier: "myViewController",
                                                                storyboard: "Main",
                                                                container: container)

假设settings的类型为MyViewController