从classname创建一个swift2类

时间:2015-10-13 10:14:05

标签: swift viewcontroller init classname

我是斯威夫特的新人。

在目标C中,我从其类名:

推送自定义UIViewController create
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)
  

错误:致命错误:在打开时意外发现nil   可选值

3 个答案:

答案 0 :(得分:6)

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方法的有效类名。

答案 1 :(得分:6)

我创建了一个非常简单的扩展来更快地完成此操作 https://github.com/damienromito/NSObject-FromClassName

extension NSObject {
    class func fromClassName(className : String) -> NSObject {
        let className = NSBundle.mainBundle().infoDictionary!["CFBundleName"] as! String + "." + className
        let aClass = NSClassFromString(className) as! UIViewController.Type
        return aClass.init()
    }
}

就我而言,我这样做是为了加载我想要的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)
}

答案 2 :(得分:5)

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

enter image description here

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

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