UIViewController扩展从storyboard实例化 [英] UIViewController extension to instantiate from storyboard

查看:149
本文介绍了UIViewController扩展从storyboard实例化的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试在Swift中编写一个小扩展来处理故事板中 UIViewController 的实例化。



我的想法如下:自 UIStoryboard 的方法 instantiateViewControllerWithIdentifier 需要一个标识符来实例化给定的故事板的视图控制器,为什么不在我的故事板中为每个视图控制器分配一个等于其确切类名的标识符(即 UserDetailViewController 将具有UserDetailViewController的标识符,并在UIViewController上创建一个类方法:




  • 接受 UIStoryboard 实例作为唯一参数

  • 将当前类名称作为字符串

  • 调用 instantiateViewControllerWithIdentifier ,类名作为参数

  • 获取新创建的 UIViewController 实例,并返回它



所以,而不是(将类名重复为字符串,不是很好)

  let vc = self.story board?.instantiateViewControllerWithIdentifier(UserDetailViewController)as UserDetailViewController 

它将是:

  let vc = UserDetailViewController.instantiateFromStoryboard(self.storyboard!)

我过去常常在Objective-C中使用以下类别:

  +(instancetype )instantiateFromStoryboard:(UIStoryboard *)storyboard 
{
return [storyboard instantiateViewControllerWithIdentifier:NSStringFromClass([self class])];
}

但我完全坚持使用Swift版本。我希望有某种方法可以做到这一点。
我尝试了以下内容:

 扩展名UIViewController {
class func instantiateFromStoryboard(storyboard:UIStoryboard) - > ; Self {
return storyboard.instantiateViewControllerWithIdentifier(NSStringFromClass(Self))
}
}

返回自我而不是 AnyObject 允许类型推断工作。否则,我必须抛出这个方法的每一个返回,这很烦人,但也许你有一个更好的解决方案?



这给了我错误:使用未解析的标识符'Self'
NSStringFromClass 部分似乎是问题所在。



您怎么看?




  • 有没有办法从类函数返回 Self ? / p>


  • 如果不需要每次都抛出返回值,你将如何工作? (即保持 - >自我作为返回值)




谢谢。

解决方案

如何将扩展名写入 UIStoryboard 而不是 UIViewController

  extension UIStoryboard {
func instantiateVC< T :UIViewController>() - > T' {
//获取Swift
中类的类名和demangle如果让name = NSStringFromClass(T.self)?. componentsSeparatedByString(。)。last {
return instantiateViewControllerWithIdentifier(name )作为? T
}
返回nil
}

}

即使采用这种方法,使用方的成本也很低。

 让vc:UserDetailViewController? = aStoryboard.instantiateVC()


I'm trying to write a little extension in Swift to handle instantiation of a UIViewController from a storyboard.

My idea is the following: Since UIStoryboard's method instantiateViewControllerWithIdentifier needs an identifier to instantiate a given storyboard's view controller, why don't assign every view controller in my storyboard an identifier equal to its exact class name (i.e a UserDetailViewController would have an identifier of "UserDetailViewController"), and, create a class method on UIViewController that would:

  • accept a UIStoryboard instance as a unique parameter
  • get the current class name as a string
  • call instantiateViewControllerWithIdentifier on the storyboard instance with the class name as a parameter
  • get the newly created UIViewController instance, and return it

So, instead of (which repeats the class name as a string, not very nice)

let vc = self.storyboard?.instantiateViewControllerWithIdentifier("UserDetailViewController") as UserDetailViewController

it would be:

let vc = UserDetailViewController.instantiateFromStoryboard(self.storyboard!)

I used to do it in Objective-C with the following category:

+ (instancetype)instantiateFromStoryboard:(UIStoryboard *)storyboard
{
    return [storyboard instantiateViewControllerWithIdentifier:NSStringFromClass([self class])];
}

But I'm completely stuck with the Swift version. I hope is that there is some kind of way to do it. I tried the following:

extension UIViewController {
    class func instantiateFromStoryboard(storyboard: UIStoryboard) -> Self {
        return storyboard.instantiateViewControllerWithIdentifier(NSStringFromClass(Self))
    }
}

Returning Self instead of AnyObject allows the type inference to work. Otherwise, I would have to cast every single return of this method, which is annoying, but maybe you have a better solution?

This gives me the error: Use of unresolved identifier 'Self' The NSStringFromClass part seems to be the problem.

What do you think?

  • Is there any way to return Self from class functions?

  • How would you get this working without the need to cast the return value every time? (i.e keeping -> Self as return value)

Thanks.

解决方案

How about writing an extension to UIStoryboard instead of UIViewController?

extension UIStoryboard {
    func instantiateVC<T: UIViewController>() -> T? {
        // get a class name and demangle for classes in Swift
        if let name = NSStringFromClass(T.self)?.componentsSeparatedByString(".").last {
            return instantiateViewControllerWithIdentifier(name) as? T
        }
        return nil
    }

}

Even adopting this approach, cost of an use side is low as well.

let vc: UserDetailViewController? = aStoryboard.instantiateVC()

这篇关于UIViewController扩展从storyboard实例化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆