Swift 自定义TabBar, 改变高度

2019-05-16  本文已影响0人  fordG

系统tabBarController的结构发现, controller部分是放在UITransitionView上面, 想要自定义TabBar改变高度, 必须要改变这俩个的高度, 页面才能很好的适配,不至于出现controller无法铺满屏幕, 在viewDidLayoutSubviews里面去改变 tabBar的高度吗,可以获得你想要的高度, 图片可以我使用的是iconFont生成UIImage
贴上代码

import UIKit
import SnapKit

class TabBarController: UITabBarController {
    
    var selectButton: UIButton?
    
//    var tabIcons = [UILabel]()
//    var tabTitles = [UILabel]()
    
    var newTab: UIView?
    
    
    
    lazy var tabHeight: CGFloat = {
        return CGFloat(isiPhoneX() ? (42 + 32) : 42)
    }()

    override func viewDidLoad() {
        super.viewDidLoad()

        // Do any additional setup after loading the view.
        self.view.backgroundColor=UIColor.white
        setupChildController()
//        setupTabBar()
    }
    
    
    func setupChildController() {
        
        let home = BaseNavigationController(rootViewController: HomeViewController())
        let market = BaseNavigationController(rootViewController: MarketViewController())
        let classRoom = BaseNavigationController(rootViewController: ClassRoomViewController())
        let collection = BaseNavigationController(rootViewController: CollectionViewController())
        let mine = BaseNavigationController(rootViewController: MineViewController())
    
        var controllerArray = [home, market, classRoom, collection, mine]
        let iconArr = [Icon.Vegetables, Icon.Market, Icon.ClassRoom, Icon.Collection, Icon.Mine]
        let titleArr = ["首页", "市集", "课堂", "收藏", "我的"]
        for i in 0...controllerArray.count-1{
            let controller = controllerArray[i]
            controller.tabBarItem.title = titleArr[i]
            let selectImage = UIImage(iconfont: iconArr[i].rawValue, fontSize: 7, color: UIColor.red)
            selectImage.withRenderingMode(.alwaysOriginal)
            controller.tabBarItem.selectedImage = selectImage
            let normalImage = UIImage(iconfont: iconArr[i].rawValue, fontSize: 7, color: UIColor.purple)
            controller.tabBarItem.image = normalImage.withRenderingMode(.alwaysOriginal)
            
        }
        self.viewControllers = controllerArray
        //此处设置需注意, 设置了需要在Didlayoutsubviews里面去改变size要不会出现遮挡问题
        //self.tabBar.backgroundImage = UIImage.imageWithColor(color: UIColor.white, size: self.tabBar.frame.size)
        self.tabBar.tintColor = UIColor.red //选中是的颜色
        self.tabBar.shadowImage = UIImage() //去除选择分割线
        self.tabBar.unselectedItemTintColor = UIColor.purple
    }
    
//    func setupTabBar() {
//        let rect = self.tabBar.frame
//        print(rect)
//        self.tabBar.removeFromSuperview()
//        self.tabBar.isHidden = true
//        newTab = UIView(frame: CGRect(x: 0, y: self.view.frame.size.height - tabHeight, width: rect.width, height: tabHeight))
//        setupTabItems(tab: newTab!)
//        newTab!.backgroundColor = UIColor.gray
//        self.view.addSubview(newTab!)
//    }
//
//    func setupTabItems(tab: UIView) {
//        let count = self.viewControllers?.count ?? 0
//        let iconArr = [Icon.Home, Icon.Market, Icon.ClassRoom, Icon.Collection, Icon.Mine]
//        let titleArr = ["首页", "市集", "课堂", "收藏", "我的"]
//        let selectColor = UIColor.red
//        let normalColor = UIColor.gray
//        let width = view.frame.size.width / CGFloat(count)
//        for i in 0...self.viewControllers!.count-1{
//            let x = width * CGFloat(i)
//            let item = UIView(frame: CGRect(x: x, y: 0, width: width, height: tabHeight))
//            item.backgroundColor = UIColor.white
//            let itemIcon = UILabel(iconfont: iconArr[i].rawValue, frame: CGRect(x: 0, y: 5, width: width, height: 25), fontSize: 24)
////            name.text = String(i)
//            item.addSubview(itemIcon)
//            let itemTitle = UILabel(frame: CGRect.zero)
//            itemTitle.font = UIFont.systemFont(ofSize: 10)
//            itemTitle.textAlignment = .center
//            item.addSubview(itemTitle)
//            itemTitle.snp.makeConstraints { (make) in
//                make.height.equalTo(15)
//                make.left.equalTo(itemIcon)
//                make.right.equalTo(itemIcon)
//                make.top.equalTo(itemIcon.snp.bottom)
//            }
//            itemTitle.text = titleArr[i]
//            if(i == 0){
//                itemIcon.textColor = selectColor
//                itemTitle.textColor = selectColor
//            }else{
//                itemIcon.textColor = normalColor
//                itemTitle.textColor = normalColor
//            }
//            tabIcons.append(itemIcon)
//            tabTitles.append(itemTitle)
//            item.tag = 1000 + i
//            item.viewCallBack = {  [unowned self] in
//                self.selectedIndex = i
//                for index in 0...self.tabIcons.count-1{
//                    let icon = self.tabIcons[index]
//                    let title = self.tabTitles[index]
//                    if(i == index){
//                        icon.textColor = selectColor
//                        title.textColor = selectColor
//                    }else{
//                        icon.textColor = normalColor
//                        title.textColor = normalColor
//                    }
//                }
//            }
//            tab.addSubview(item)
//        }
//    }
//

//改变系统tabBar高度
    override func viewDidLayoutSubviews() {
        super.viewDidLayoutSubviews()
  
    //确保代码执行一次
        DispatchQueue.once {
            self.tabBar.frame = CGRect(x: self.tabBar.frame.origin.x, y: self.view.frame.size.height - tabHeight, width: self.tabBar.frame.size.width, height: tabHeight)
            self.tabBar.backgroundImage = UIImage.imageWithColor(color: UIColor.white, size: rect.size)
        }
    }
//
//    @objc func tabTap(tap: UITapGestureRecognizer) {
//
//        let selecIndex = tap.view?.tag ?? 1000 - 1000
//        print(selecIndex)
//
//    }
//
//    func changeTabView(){
//        self.tabBar.isHidden = true
//        self.newTab?.isHidden = self.hidesBottomBarWhenPushed
//    }

}
import UIKit
import CoreText

// 通过枚举获取你定义好的iconfont图标
public enum Icon: String {
    case Home = "\u{e663}"
    case Market = "\u{e60d}"
    case ClassRoom = "\u{e617}"
    case Collection = "\u{e67c}"
    case Mine = "\u{e670}"
    case Back = "\u{e65b}"
    case Money = "\u{e61d}"
    case AddFriend = "\u{e61a}"
    case Order = "\u{e601}"
    case Add = "\u{e6ec}"
    case Search = "\u{e6a8}"
    case Vegetables = "\u{e600}"
    case Shopping = "\u{e64b}"
    case Navgation = "\u{e625}"
    case History = "\u{e6c7}"
    case Notice = "\u{e67d}"
    case Setting = "\u{e616}"
    
}

class IconFont: NSObject {
    var code:String       //标准解析格式 比如:"\u{a62b}"
    var name:String       //图标的名字.一般为中文,比如:设置
    var descr:String!     //图标作用和备注
    var labelText:String! //可以直接赋值给UILabel,以系统字体大小为基准
    var iconImage:UIImage!//生成一个一般的iconImge  如果需要其他大小的可以自己调整, 使用第二个初始化中代码段。
    
    ///初始化图标
    /// - important : fontsize可通过外部font的size调整,而且必须设置UILabel的font,否则无法正常显示。比如:
    /// - label.font = UIFont.init(name: "IconFont", size: UIFont.systemFontSize)
    /// - parameter code: 标准解析格式,比如:"\u{a62b}"
    /// - parameter name:图标的中文名
    init(code:String, name:String) {
        self.code = code
        self.name = name
        //为UILabel使用的做准备
        let label = UILabel()
        
        label.text = code
        self.labelText = label.text
    }
    ///初始化图标 ,图片可用
    /// - important :图片大小由iconFont的fontSize自动计算决定。建议UIImageView大小参考打印值,这样的图片显示效果是最好的。
    /// - parameter code: 标准解析格式,比如:"\u{a62b}"
    /// - parameter name:图标的中文名
    /// - parameter fontSize:图标(字体大小)
    /// - parameter color:图标的颜色
    convenience init(code:String, name:String, fontSize:CGFloat, color:UIColor){
        self.init(code: code, name: name)
        //计算文本rect
        let nscode = code as NSString
        let rect = nscode.boundingRect(with:CGSize(width: 0.0, height: 0.0) , options: .usesLineFragmentOrigin, attributes: [NSAttributedString.Key.font :  UIFont(name: "IconFont", size: fontSize)!], context: nil)
        let size = rect.size
        print("建议图片大小:\(size)") //建议UIImageView大小参考打印值
        let label = UILabel(frame: CGRect(x: 0, y: 0, width: size.width, height: size.height))
        label.font = UIFont(name: "IconFont", size: fontSize)
        label.textAlignment = .center
        label.textColor = color
        label.text = code
        UIGraphicsBeginImageContextWithOptions(size, false, UIScreen.main.scale)
        label.layer.render(in: UIGraphicsGetCurrentContext()!)
        let image = UIGraphicsGetImageFromCurrentImageContext()
        self.iconImage = image
    }
    
    ///直接生成该图标的UIImage 对象
    /// - important :图片大小由iconFont的fontSize自动计算决定。建议UIImageView大小参考打印值,这样的图片显示效果是最好的。
    /// - parameter fontSize:图标(字体大小)
    /// - parameter color:图标的颜色
    func iconFontImage(fontSize:CGFloat, color:UIColor) -> UIImage {
        //计算iconFont的宽高
        let nscode = code as NSString
        let rect = nscode.boundingRect(with:CGSize(width: 0.0, height: 0.0) , options: .usesLineFragmentOrigin, attributes: [NSAttributedString.Key.font : UIFont.systemFont(ofSize: fontSize)], context: nil)
        let size = rect.size
        print("建议图片大小:\(size)") //建议UIImageView大小参考打印值
        UIGraphicsBeginImageContextWithOptions(size, false, UIScreen.main.scale)
        let label = UILabel(frame: CGRect(x: 0, y: 0, width: size.width, height: size.height))
        label.font = UIFont(name: "IconFont", size: fontSize) //??为什么用IconFont和字体文件名一致(首字母大小写无所谓),但是不能换为其他的,哪怕你的iconFont的名字为其他的。
        label.textAlignment = .center
        label.text = code
        label.textColor = color
        label.layer.render(in: UIGraphicsGetCurrentContext()!)   //??深入了解layer
        let image = UIGraphicsGetImageFromCurrentImageContext()
        return image!
    }
}

//MARK: - 扩展UILable
extension UILabel{
    ///直接通过UILabel加载iconfont
    /// - parameter iconfont: 图标的编码标准格式如:"\u{a626}"
    convenience init(iconfont code:String, frame: CGRect ,fontSize:CGFloat) {
        self.init(frame: frame)
        self.text = code
        self.font = UIFont(name: "IconFont", size: fontSize)
        self.textAlignment = .center
    }
}


//MARK: - 扩展UIImage
extension UIImage {
    ///直接通过生成UIImage
    /// - parameter code: 图标的标准编码 如:"\u{a626}"
    /// - parameter fontSize: 图标的字体大小,建议设置为UIImageView的高度,这样最合适,效果最好。
    /// - parameter color: 图标的颜色。
    convenience init(iconfont code:String,fontSize:CGFloat, color:UIColor){
        let iconImage = IconFont(code: code, name: "", fontSize: fontSize, color: color).iconImage
        let iconData:Data = iconImage!.pngData() ?? iconImage!.jpegData(compressionQuality: 1.0) ?? Data()
//            UIImageJPEGRepresentation(iconImage!, 1.0
        self.init(data: iconData)!
    }
    
}
override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        self.hidesBottomBarWhenPushed = true
    }
public extension DispatchQueue {
    private static var _onceTracker = [String]()
    
    class func once(file: String = #file, function: String = #function, line: Int = #line, block:()->Void) {
        let token = file + ":" + function + ":" + String(line)
        once(token: token, block: block)
    }
    
    /**
     Executes a block of code, associated with a unique token, only once.  The code is thread safe and will
     only execute the code once even in the presence of multithreaded calls.
     
     - parameter token: A unique reverse DNS style name such as com.vectorform.<name> or a GUID
     - parameter block: Block to execute once
     */
    class func once(token: String, block:()->Void) {
        objc_sync_enter(self)
        defer { objc_sync_exit(self) }
        
        
        if _onceTracker.contains(token) {
            return
        }
        
        _onceTracker.append(token)
        block()
    }
}
上一篇下一篇

猜你喜欢

热点阅读