从classname创建swift2类

从classname创建swift2类,swift,viewcontroller,init,classname,Swift,Viewcontroller,Init,Classname,我是斯威夫特的新手 在objective C中,我将自定义UIViewController从其类名中创建: NSString *classString = "customViewController"; UIViewController *vc = [[NSClassFromString(classString) alloc] init]; [self pushViewController:vc animated:YES]; 我无法在swift中构建类,这不起作用: let myClass =

我是斯威夫特的新手

在objective C中,我将自定义UIViewController从其类名中创建:

NSString *classString = "customViewController";
UIViewController *vc = [[NSClassFromString(classString) alloc] init];
[self pushViewController:vc animated:YES];
我无法在swift中构建类,这不起作用:

let myClass = NSClassFromString("customViewController") as! UIViewController.Type
let vc = myClass.init()
self.presentViewController(vc, animated: true, completion: nil)
错误:致命错误:在展开数据包时意外发现零 可选值


NSClassFromString
使用完全限定的类名

class CustomViewController: UIViewController { }

let className = NSStringFromClass(CustomViewController.self)
// let className = "MyAppName.CustomViewController" // Equivalent
let aClass = NSClassFromString(className) as! UIViewController.Type
let viewController = aClass.init()
或者,使用
@objc
属性覆盖完全限定类名:

@objc(CustomViewController)
class CustomViewController: UIViewController { }

let className = NSStringFromClass(CustomViewController.self)
// let className = "CustomViewController" // Equivalent
let aClass = NSClassFromString(className) as! UIViewController.Type
let viewController = aClass.init()

无论哪种方式,
NSStringFromClass
都将始终返回
NSClassFromString
方法的有效类名。

失败的原因是您引用的视图控制器类名(
customViewController
)未完全由模块名限定。这可以在自定义类名下面的Interface Builder中找到:

您应该更改类名字符串以表示视图控制器的完全限定名,例如:

let myClass = NSClassFromString("MyProject.customViewController") as! UIViewController.Type

我创建了一个非常简单的扩展来更快地完成这项工作


在本例中,我这样做是为了加载所需的ViewController:

override func viewDidLoad() {
    super.viewDidLoad()
    let controllers = ["SettingsViewController", "ProfileViewController", "PlayerViewController"]
    self.presentController(controllers.firstObject as! String)

}

func presentController(controllerName : String){
    let nav = UINavigationController(rootViewController: NSObject.fromClassName(controllerName) as! UIViewController )
    nav.navigationBar.translucent = false
    self.navigationController?.presentViewController(nav, animated: true, completion: nil)
}

没有
@objc
注释,它在操场上不起作用。@SteveWilford
NSClassFromString
使用
@objc
属性中指定的名称。此代码也适用于application@SteveWilford添加了使用完全限定名称的示例。如果此操作不起作用,应用程序将崩溃,并出现相同的致命错误。我必须从字符串中获取类名,与您的另外两个示例不同,抱歉…@DamienRomito使用XCode 7在Swift 2中重复检查了两个示例,两个示例都按预期工作。我对答案进行了编辑以使其更清晰。模块名称最好通过
NSBundle.mainBundle().infoDictionary来确定![“CbundleExecutable”]as!字符串
谢谢!!!!字符串必须以项目名称“MyProject.customViewController”作为前缀,更好的做法是只使用
@objc
标记来命名类,而不使用非模块特定的名称,不是吗?类似于
@objc(CustomViewController)
…所有解决方案中最好的解决方案就像一个符咒
override func viewDidLoad() {
    super.viewDidLoad()
    let controllers = ["SettingsViewController", "ProfileViewController", "PlayerViewController"]
    self.presentController(controllers.firstObject as! String)

}

func presentController(controllerName : String){
    let nav = UINavigationController(rootViewController: NSObject.fromClassName(controllerName) as! UIViewController )
    nav.navigationBar.translucent = false
    self.navigationController?.presentViewController(nav, animated: true, completion: nil)
}