iOS swift NSClassFromString将字符串转换成类名

在oc中将字符串转换成类名直接调用NSClassFromString("classname")即可,但是到了swift中变的麻烦多了

swift中如果要将字符串转换为类型需要以下几个步骤

1.获取包名

var name = Bundle.main.object(forInfoDictionaryKey: "CFBundleExecutable") as? String//这是获取项目的名称,

这个特别需要注意一点的是如果你的包名中有'-'横线这样的字符,在拿到包名后,还需要把包名的'-'转换成'_'下横线,这点特别坑(折腾了半天才找到原因?)

  name = name?.replacingOccurrences(of: "-", with: "_")

2.包名和类名按照一定的格式组合成新的字符串"包名.类名",这里HomeVC是我想要转换类名的字符串

 let className = name! + "." + "HomeVC"

3.尝试将前面组合好的字符串转换成我们想要的类名 由于NSClassFromString返回的是AnyClass,这里要转换成UIViewController.Type类型

guard let cls = NSClassFromString(className) as? UIViewController.Type  else{
    fatalError("转换失败")
}

4.转换成功后我们就可以用前面转换好类名来创建对象了

let vc = cls.init()

demo源码:

//
//  HXQTabbarController.swift
//  hxquan-swift
//
//  Created by Tiny on 2018/10/25.
//  Copyright © 2018年 hxq. All rights reserved.
//

import UIKit

class HXQTabbarController: UITabBarController {

    override func viewDidLoad() {
        super.viewDidLoad()

        // Do any additional setup after loading the view.
        
        setupUI()
    }
    
    private func setupUI(){
        
        //设置内容
        let datas:[[String:String]] = [
            ["className":"HXQHomeVC","title":"首页","image":"tab_battle_nor","selectedImage":"tab_battle_sel"],
            ["className":"HXQCircleVC","title":"圈子","image":"tab_circle_nor","selectedImage":"tab_circle_sel"],
            ["className":"HXQMallVC","title":"商城","image":"tab_mall_nor","selectedImage":"tab_mall_sel"],
            ["className":"HXQMineVC","title":"我的","image":"tab_mine_nor","selectedImage":"tab_mine_sel"],
        ]
        
        for dict in datas {
            
            var name = Bundle.main.object(forInfoDictionaryKey: "CFBundleExecutable") as? String//这是获取项目的名称,
            /**
             * 如果你的工程名字中带有“-” 符号  需要加上 replacingOccurrences(of: "-", with: "_") 这句代码把“-” 替换掉  不然还会报错 要不然系统会自动替换掉 这样就不是你原来的包名了 如果不包含“-”  这句代码 可以不加
             */
            name = name?.replacingOccurrences(of: "-", with: "_")
            let className = name! + "." + dict["className"]!
            guard let vc = NSClassFromString(className) as? UIViewController.Type,
                  let image = UIImage(named: dict["image"]!),
                  let selectedImage = UIImage(named: dict["selectedImage"]!) else{
                fatalError("类名或者图片名错误")
            }
            setupChildViewController(childVc: vc.init(), title: dict["title"]!, image: image, selectedImage: selectedImage)
        }
    }
    
    private func setupChildViewController(childVc:UIViewController , title:String , image:UIImage , selectedImage:UIImage){
        tabBar.tintColor = .red
        //创建tabbarItem
        childVc.title = title
        childVc.tabBarItem.image = image.withRenderingMode(.alwaysOriginal)
        childVc.tabBarItem.selectedImage = selectedImage.withRenderingMode(.alwaysOriginal)
        let navc = HXQNavigationController(rootViewController: childVc)

        //设置阴影
//        childVc.navigationController?.navigationBar.layer.shadowOffset = CGSize(width: 0, height: 5)
//        childVc.navigationController?.navigationBar.layer.shadowOpacity = 0.2
//        childVc.navigationController?.navigationBar.layer.shadowRadius = 5
//        self.navigationController?.navigationBar.layer.shadowColor = UIColor.black.cgColor
//
//        childVc.navigationController?.navigationBar.layer.shadowPath = UIBezierPath(rect: (childVc.navigationController!.navigationBar.bounds)).cgPath

        addChild(navc)
    }
}