關於一些不同尋常的tabBar的使用

在實際開發中,系統的原生控件並不能滿足我們的需求,這個時候就需要自己去自定義這個控件,自定義控件需要自己對原生控件結構非常瞭解。今天,這裏來講一下不同尋常的tabBar。

原則:儘量利用系統自帶的TabBar.只改需要改的地方

不同尋常的tabBar 類型一:這種基本上是重寫了整個tabbar,然後根據自己的需求來定義view的風格
步驟:
1.把自帶的TaBBar條給隱藏掉,添加自己的view

 let rect = self.tabBar.frame
 self.tabBar.removeFromSuperview()
 customTabBar = CustomTabBar()
 customTabBar.customDelegate = self
 customTabBar.frame = rect
 self.view.addSubview(customTabBar)

2.自己做一個View,上面放幾個按鈕,設定按鈕的點擊事件,並設置selectIndex

import UIKit

protocol GGTabBarDelegate: NSObjectProtocol {
    func tabBarSelectedFromBtnIndexToBtnIndex(tabBar:CustomTabBar,fromBtnIndex:Int,toBtnIndex:Int)
}

class CustomTabBar: UIView {

    weak var customDelegate:GGTabBarDelegate?
    /**
     *  設置之前選中的按鈕
     */
    var selectedBtn:ItemButton?

    override init(frame: CGRect) {
        super.init(frame: frame)
        self.backgroundColor = UIColor.whiteColor() //設置tabBar的背景色
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
    }

    func addItemBtn(image:UIImage,selectedImage:UIImage,title:String) -> Void {
        let itemBtn = ItemButton(frame: CGRectZero)
        itemBtn.titleLabel?.font = UIFont.systemFontOfSize(12)
        itemBtn.setImage(image, forState: .Normal)
        itemBtn.setImage(selectedImage, forState: .Selected)
        itemBtn.setTitle(title, forState: .Normal)
        itemBtn.addTarget(self, action: #selector(CustomTabBar.btnClicked(_:)), forControlEvents: .TouchUpInside)
        self.addSubview(itemBtn)
        //規定默認選中按鈕
        if self.subviews.count == 1 {
            btnClicked(itemBtn)
        }

    }


    func btnClicked(btn:ItemButton) -> Void {
       //設置當前選中的按鈕
        selectedBtn?.selected = false

        btn.selected = true

        selectedBtn = btn

        if ((customDelegate?.respondsToSelector(Selector("tabBarSelectedFromBtnIndexToBtnIndex:fromBtnIndex:toBtnIndex:"))) != nil) {
            customDelegate?.tabBarSelectedFromBtnIndexToBtnIndex(self, fromBtnIndex: (selectedBtn?.tag)!, toBtnIndex: btn.tag)
        }

    }

    override func layoutSubviews() {
        super.layoutSubviews()

        let width = self.bounds.size.width
        let height = self.bounds.size.height

        let count = self.subviews.count


        for i in 0..<count {
            let btn = self.subviews[i] as! ItemButton
            btn.tag = i

            let x = CGFloat(i) * width / CGFloat(count)
            let w = width / CGFloat(count)

            btn.frame = CGRect(x: x, y: 0, width: w, height: height)

        }
    }

在這裏爲了更好的實現自定義的效果,用了自定義的按鈕,讓按鈕圖片文字上下居中顯示

import UIKit
class ItemButton: UIButton {
    override init(frame: CGRect) {
        super.init(frame: frame)
        self.setTitleColor(UIColor.grayColor(), forState: .Normal) //normal title color
        self.setTitleColor(UIColor.orangeColor(), forState: .Selected)//selected title color
    }
    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
    }

    override func layoutSubviews() {
       super.layoutSubviews()

        //imageView
       var center = self.imageView?.center
        center?.x = self.frame.size.width / 2
        center?.y = (self.imageView?.frame.size.height)! / 2 + 2.5
        self.imageView?.center = center!
        //titleLabel
        var rect = self.titleLabel?.frame
        rect?.origin.x = 0
        rect?.origin.y = (self.imageView?.frame.size.height)! 
        rect?.size.width = self.frame.size.width
        self.titleLabel?.frame = rect!
        self.titleLabel?.textAlignment = .Center  
    }
}

3.關聯各個childViewController,覆蓋相關事件

    func addChildVC(childVC:UIViewController,title:String,imageName:String,selectedImageName:String) -> Void {
        customTabBar.addItemBtn(UIImage(named: imageName)!, selectedImage: UIImage(named: selectedImageName)!, title: title)

        //添加導航控制器
        let nav = UINavigationController(rootViewController: childVC)

        self.addChildViewController(nav)

    }

    func tabBarSelectedFromBtnIndexToBtnIndex(tabBar: GGAnotherTabBar, fromBtnIndex: Int, toBtnIndex: Int) {
        self.selectedIndex = toBtnIndex
    }

上面這種自定義之後,又需要在push的時候隱藏掉tabBar,這個時候我們需要寫一個來隱藏的方法,在push之前設爲hide = true,在pop(或者viewAppear裏)設爲hide = false

import UIKit

extension UIViewController {
    func hidesCustomBarWhenPushed(hide:Bool) -> Void {
        let tabBarController = self.tabBarController as! MainViewController
        let customTabBar = tabBarController.customTabBar

        if hide {
//            UIView.animateWithDuration(0.24, animations: {
//                UIView.setAnimationCurve(.EaseOut)
                customTabBar.frame.origin.x = 0 - UIScreen.mainScreen().bounds.width
//            })

        }else {

//            UIView.animateWithDuration(0.24, animations: {
//                UIView.setAnimationCurve(.EaseOut)
                customTabBar.frame.origin.x = 0
//            }) 
        }
    }
}

在這裏,一直想用動畫的形式來表現,無奈做不出系統那麼好的效果,就乾脆去掉了動畫

不同尋常的tabBar 類型二:怎麼說呢,就是網上流傳的和新浪微博那樣的,這種就比較簡單了,不需要重寫整個tabBar,只需要繼承自UITabBar,然後在初始化的時候,添加一個特殊按鈕(就是因爲這個按鈕特殊,所以才需要自定義),並綁定點擊事件用代理回調,最後在layoutSubviews()方法裏設置位置佈局.

override init(frame: CGRect) {
    super.init(frame: frame)
    let btn = UIButton()
    //configure the special button
    plusBtn = btn 
}      
override func layoutSubviews() {
        super.layoutSubviews()
        //設置中間按鈕的位置
        plusBtn?.center.x = self.frame.size.width * 0.5
        plusBtn?.center.y = self.frame.size.height * 0.5

        //設置其他item的位置
        let w = self.frame.size.width / 3 /////////這裏一共爲3個
        var itemIndex = 0

        for item in self.subviews {
            let c = NSClassFromString("UITabBarButton")
            if item.isKindOfClass(c!) {
                item.frame.origin.x = (CGFloat)(itemIndex) * w
                item.frame.size.width = w

                itemIndex += 1

                if itemIndex == 1 {
                    itemIndex += 1
                }

            }
        }


    }

tabBar自定義完成後,我們使用KVC的形式來將customTabBar設爲UITabBarController的tabBar:

        let tabBar = CustomTabBar()
        tabBar.customDelegate = self
        ////////kvc
        self.setValue(tabBar, forKey: "tabBar")

添加子控制器部分代碼

  func addChildVC(childVC:UIViewController,title:String,imageName:String,selectedImageName:String) -> Void {
        childVC.tabBarItem.title = title

        childVC.tabBarItem.image = UIImage(named: imageName)

        childVC.tabBarItem.selectedImage = UIImage(named: selectedImageName)?.imageWithRenderingMode(.AlwaysOriginal)
        //文字選中和未選中顏色
        childVC.tabBarItem.setTitleTextAttributes([NSForegroundColorAttributeName:UIColor.grayColor()], forState: .Normal)

        childVC.tabBarItem.setTitleTextAttributes([NSForegroundColorAttributeName:UIColor.orangeColor()], forState: .Selected)
        //添加導航控制器
        let nav = UINavigationController(rootViewController: childVC)

        self.addChildViewController(nav)

    }

    func tabBarDidClickPlusButton(tabBar: GGTabBar) {
        self.presentViewController(AddViewController(), animated: true, completion: nil)
    }

不同尋常的tabBar 類型三:沒有什麼比較特殊的,現在我就想最中間那個item不顯示title,顯示一個巨大的image,來表明這個模塊就是要吸引你的注意O__O “…,這裏說一個最簡單的方法,在StoryBoard裏 拖一個tabBarController和幾個子控制器
將那個與衆不同的item的title去掉,image,selectedImage照常設置,
下面進入代碼部分

class MainTabBarViewController: UITabBarController {

    override func viewDidLoad() {
        super.viewDidLoad()

        // Do any additional setup after loading the view.
        for childVC in self.viewControllers! {
            childVC.tabBarItem.image = childVC.tabBarItem.image?.imageWithRenderingMode(.AlwaysOriginal)
            childVC.tabBarItem.selectedImage = childVC.tabBarItem.selectedImage?.imageWithRenderingMode(.AlwaysOriginal)
            childVC.tabBarItem.setTitleTextAttributes([NSForegroundColorAttributeName:UIColor.grayColor()], forState: .Normal) //normal title color

            childVC.tabBarItem.setTitleTextAttributes([NSForegroundColorAttributeName:UIColor.orangeColor()], forState: .Selected) //selected title color
        }


    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
    override func viewDidLayoutSubviews() {
        super.viewDidLayoutSubviews()
        for i in 0..<(self.viewControllers?.count)! {
            if i == 1 {
                let vc = self.viewControllers![i]

                vc.tabBarItem.imageInsets = UIEdgeInsets(top: 5, left: 0, bottom: -5, right: 0)
            }

        }
    }

另附上:(這裏是使用系統的tabBar,也就說這個tabBarViewController的tabBar並沒有被removeFromSuperView或者Hidden=true)
nav push到下一個vc的時候隱藏tabBar, 返回時顯示tabBar,只需要這樣做:

self.hidesBottomBarWhenPushed = true
self.navigationController?.pushViewController(nextVC, animated: true)
self.hidesBottomBarWhenPushed = false
發佈了67 篇原創文章 · 獲贊 12 · 訪問量 15萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章