自定义Tabbar

swift4.0实现自定义Tabbar,实现按钮中间突出,并且突出部分点击事件响应,主要代码调用如下
**实现思想,
1.中间按钮为继承自button的类,在内部设置中间按钮的图层,
2.其他按钮也是继承UIButton的类设置title和image显示的位置
3.创建一个继承自UIView的类,在这里设置tabbar的排布方式定义协议,方法,供外界调用
4.创建一个继承自UITabBarController的类,在这个类中创建tabbar的元素,

**

`import UIKit

class CQ_TabbarController: UITabBarController {

var lastSelectIndex:NSInteger?
var redPoint:UIView?
var popDelegate:Any?
var composeButton:UIButton?
var CustomTabbar:CQ_Tabbar?

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    self.tabBar.isHidden = true
    self.tabBar.removeFromSuperview()
    for  childView in self.tabBar.subviews{
        if childView .isKind(of: (CQ_Tabbar.self)) {
            childView .removeFromSuperview()
        }
    }
}

override func viewDidLoad() {
    super.viewDidLoad()

    addChildVC()
    setUpTabbar()

}

func setUpTabbar() {

    let tabbar = CQ_Tabbar()

    tabbar.setItems(items: self.items)
    tabbar.Delegate = self
    tabbar.backgroundColor = UIColor.init(patternImage: UIImage(named: "tab_backgroundX")!)
    tabbar.frame = CGRect(x: 0, y:(ScreenH - CGFloat(TabbarHeight)) , width: ScreenW, height: ScreenH)
    view.addSubview(tabbar)
    // warning 调用选中的这个方法,必须在初始化设置后在调用,不然会报错

// tabbar.setSelectIndexItem(Index: 1)
CustomTabbar = tabbar
}

func setupButton(){
    let rect = self.tabBar.bounds
    let w = rect.size.width / CGFloat(self.childViewControllers.count - 1)
    composeButton?.frame = rect.insetBy(dx: 2 * w, dy: 0)

    composeButton?.height = CGFloat(Int(TabbarHeight))

}

func addChildVC(){

    let homeVC = HomeViewController()
    addChildVC(childVC: homeVC, title: "首页", imageName: "新闻组管理 (1)", selectedImage: "新闻组管理")

    let NewVC = NewViewController()
    addChildVC(childVC: NewVC, title: "新闻", imageName: "Push", selectedImage: "PushSele")

    let PushVC = PushViewController()

// addChildVC(childVC: PushVC, title: “大发”, imageName: “tab_Irregular”, selectedImage: “tabBar_icon_customer”)

    addChildVC(childVC: PushVC, title: "发布", imageName: "添加", selectedImage: "添加")

    let DataVC = DataViewController()
    addChildVC(childVC: DataVC, title: "发现", imageName: "News", selectedImage: "NewsSele")

    let profile = ProfileViewController()
    addChildVC(childVC: profile, title: "我的", imageName: "homepage_fill", selectedImage: "homepage_Sele")
}


func addChildVC(childVC:UIViewController,title:NSString,imageName:NSString,selectedImage:NSString){

    childVC.tabBarItem.title = title as String
    //设置图标
    childVC.tabBarItem.image = UIImage(named: imageName as String)

    //设置选中的图标
    var seleImage = UIImage(named: selectedImage as String)

    //不要渲染
    seleImage = seleImage?.withRenderingMode(.alwaysOriginal)
    childVC.tabBarItem.selectedImage = seleImage;

    self.items .add(childVC.tabBarItem)
    //添加为tabbar控制器的子控制器
    let nav  = CQ_NavigationController(rootViewController: childVC)
    nav.delegate = self //这个代理方必须写上,代理方法也必须实现
    self.addChildViewController(nav)
}


lazy var items:NSMutableArray = {
   let array = NSMutableArray()
    return array
}()

}

extension CQ_TabbarController:CQTabbarDelegate,UITabBarControllerDelegate,UINavigationControllerDelegate{

func tabbarSelected(tabbar:CQ_Tabbar,clickIndex:NSInteger){
    super.selectedIndex = clickIndex
}
func navigationController(_ navigationController: UINavigationController, willShow viewController: UIViewController, animated: Bool) {
 let Root:UIViewController = navigationController.viewControllers.first!
    tabBar.isHidden = true
    if viewController != Root {
        CustomTabbar?.removeFromSuperview()
        var dockFrame = CustomTabbar?.frame
        dockFrame?.origin.y = Root.view.height - CGFloat(TabbarHeight)
        if Root.view .isKind(of: UIScrollView.self){
            let scroller:UIScrollView = Root.view as! UIScrollView
            dockFrame?.origin.y += scroller.contentOffset.y
        }
        CustomTabbar?.frame = dockFrame!
        Root.view.addSubview(CustomTabbar!)
    }
}



func navigationController(_ navigationController: UINavigationController, didShow viewController: UIViewController, animated: Bool) {
    let Root:UIViewController = navigationController.viewControllers.first!
    let Nav:CQ_NavigationController  = navigationController as! CQ_NavigationController
    if viewController == Root {
        navigationController.interactivePopGestureRecognizer?.delegate = Nav.PopDelegate as? UIGestureRecognizerDelegate
        CustomTabbar?.removeFromSuperview()
        CustomTabbar?.frame = CGRect(x: 0.0, y: ScreenH - CGFloat(TabbarHeight), width: ScreenW, height: CGFloat (TabbarHeight))
        view .addSubview(CustomTabbar!)
    }

}

}
`
自定义Tabbar_第1张图片

自定义Tabbar_第2张图片

tabbar的实现部分代码

import UIKit


protocol CQTabbarDelegate:NSObjectProtocol {
    func tabbarSelected(tabbar:CQ_Tabbar,clickIndex:NSInteger)
}


class CQ_Tabbar: UIView {
    let tabbarTag = 1200
    weak var Delegate:CQTabbarDelegate?
    var selectedIndex:NSInteger?
    var currentSelectedIndex:NSInteger = 0
    var subViewCount:NSInteger = 1
    var seleButton:UIButton?
    var bigButton:CQ_TabbarBigButton?

    func setItems(items:NSArray){

        for i in 0...count {
            let tabbarItem  = items[i] as! UITabBarItem

            if i == 2 {
                //设置中间突出按钮
                let BigButton = CQ_TabbarBigButton(type: .custom)
                BigButton.tag = self.subviews.count + tabbarTag
                BigButton .setImage(tabbarItem.image, for: .normal)
                BigButton.adjustsImageWhenHighlighted = false

                //设置文字
                BigButton.setTitle(tabbarItem.title, for: .normal)
                BigButton.setTitleColor(.red, for: .normal)
                BigButton.setTitleColor(.green, for: .selected)
                BigButton.addTarget(self, action: #selector(btnClick(btn:)), for: .touchDown)
                addSubview(BigButton)
                bigButton = BigButton
            }else
            {
                let NorButton = CQ_NorTabbarButton(type: .custom)
                NorButton.tag = self.subviews.count + tabbarTag
                NorButton .setImage(tabbarItem.image, for: .normal)
                NorButton.setImage(tabbarItem.selectedImage, for: .selected)
                NorButton.adjustsImageWhenHighlighted = false
                NorButton.barItem = tabbarItem
                NorButton.setTitle(tabbarItem.title, for: .normal)


                NorButton.setTitleColor(.red, for: .normal)
                NorButton.setTitleColor(.green, for: .selected)
                NorButton.addTarget(self, action: #selector(btnClick(btn:)), for: .touchDown)
                addSubview(NorButton)


                if (self.selectedIndex != nil) {
                   subViewCount = self.selectedIndex! + 1
                }

                if (subviews.count == subViewCount) {
                    selectedIndex = subviews.count - 1
                    btnClick(btn: NorButton)
                }

            }

         }

    }

    //留给外界可以设置选中第几个item
  public  func setSelectIndexItem(Index:NSInteger){
        selectedIndex = Index
        let button = viewWithTag(tabbarTag + Index)
    btnClick(btn: button as! UIButton)

    }

    //item选中的执行事件
    func btnClick(btn:UIButton){
       seleButton?.isSelected = false
        btn.isSelected = true
        seleButton = btn
        Delegate?.tabbarSelected(tabbar: self, clickIndex: btn.tag - tabbarTag)
    }

    override func layoutSubviews() {
        super.layoutSubviews()
        let Count:NSInteger = subviews.count
        var X:CGFloat = 0
        var Y:CGFloat = 0
        let W:CGFloat = UIScreen.main.bounds.size.width / CGFloat(Count)

        var H = 49
        for i in 0..
            let btn:UIButton = subviews[i] as! UIButton
            X = CGFloat(i) * W
          //由于第三个按钮上部是突出的所以这里Y上移12
            if i == 2 {
                Y = -12
                H += 12
                 btn.frame = CGRect(x: X, y: Y, width: W, height: CGFloat(H))
            }else
            {
                //其他按钮正常位置不变
                H = 49
                 Y  = 0
                 btn.frame = CGRect(x: X, y: Y, width: W, height: CGFloat(H))
            }

        }

    }

    override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
        let PointW = 43
        let PointH = 61
        let PointX = (ScreenW - CGFloat(PointW)) / 2
        let PointY = -12
        let rect:CGRect = CGRect(x: Int(PointX), y: PointY, width: PointW, height: PointH)
        if rect.contains(point) {
            return bigButton
        }
       return super.hitTest(point, with: event)

    }

}

上面的代码只是其中一部分,我已将全部代码放到了github上上供下载的github代码下载地址

你可能感兴趣的:(Swift)