从classname创建一个swift2类

Dam*_*ito 2 init classname viewcontroller swift

我是Swift的新手.

在目标C中,我从其类名推送自定义UIViewController create:

NSString *classString = "customViewController";
UIViewController *vc = [[NSClassFromString(classString) alloc] init];
[self pushViewController:vc animated:YES];
Run Code Online (Sandbox Code Playgroud)

我无法在swift中构建类,这不起作用:

let myClass = NSClassFromString("customViewController") as! UIViewController.Type
let vc = myClass.init()
self.presentViewController(vc, animated: true, completion: nil)
Run Code Online (Sandbox Code Playgroud)

错误:致命错误:在解包可选值时意外发现nil

red*_*t84 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()
Run Code Online (Sandbox Code Playgroud)

或者,您可以使用以下@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()
Run Code Online (Sandbox Code Playgroud)

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


Dam*_*ito 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()
    }
}
Run Code Online (Sandbox Code Playgroud)

在我的情况下,我这样做加载我想要的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)
}
Run Code Online (Sandbox Code Playgroud)


Ste*_*ord 5

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

在此输入图像描述

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

let myClass = NSClassFromString("MyProject.customViewController") as! UIViewController.Type
Run Code Online (Sandbox Code Playgroud)

  • 模块名称最好由`NSBundle.mainBundle().infoDictionary!["CFBundleExecutable"]确定为!String` (2认同)