UITabBar自定义

当tabbar上有凸出的点击区域的时候(如下图),如何实现呢?
(1)tabbar完全自定义(包括UITabBarButton的自定义);
(2)只是部分自定义,因为除了加号区域,其他点击按钮,其实跟系统的并没有区别。

效果图.png
  • 以下代码采用第二种方案:
  1. BaseCustomTabBar.swift(继承自UITabBar的自定义tabbar):
/*
 自定义的tabbar
 */

import UIKit

class BaseCustomTabBar: UITabBar {
    
    //MARK: - 属性 & 事件
    let plusBtnTag = Int(1000008)
    lazy var plusBtn: UIButton = {//‘+’号按钮
        let btn = UIButton.init(type: UIButtonType.custom)
        btn.bounds = CGRect.init(x: 0, y: 0, width: 62, height: 62)
        btn.setImage(UIImage.named(name: "m21a_publish"), for: UIControlState.normal)
        btn.setImage(UIImage.named(name: "m21a_publish_cancel"), for: UIControlState.selected)
        btn.addTarget(self, action: #selector(self.plusBtnAction), for: .touchUpInside)
        btn.tag = plusBtnTag
        self.addSubview(btn)
        return btn
    }()
    
    @objc func plusBtnAction() {//‘+’号按钮点击事件
        
    }
    
    //MARK: - 生命周期
    override func layoutSubviews() {
        super.layoutSubviews()
        // 布局子控件
        let count = (self.items?.count ?? 0) + 1
        let btnW = self.frame.size.width/CGFloat(count)
        let btnH = (self.frame.size.height) > 49 ? 49 : self.frame.size.height
        var i:Int = 0
        for tabBarButton in self.subviews {
            // 取出UITabBarButton
            if tabBarButton.isKind(of: NSClassFromString("UITabBarButton")!) {
                if i == 2 {
                    i = I+1
                }
                tabBarButton.frame = CGRect.init(x: btnW*CGFloat(i), y: 0, width: btnW, height: btnH)
                i = I+1
            }
        }
        // plusButton
        self.plusBtn.center = CGPoint.init(x: self.frame.size.width * 0.5, y: 0)
    }
    
    
    //MARK: - 解决“子视图超出父视图范围,无法响应点击事件的问题”
    override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
        let view = super.hitTest(point, with: event)
        if view == nil {
            for subView in self.subviews {
                let myPoint = subView.convert(point, from: self)
               //subView.superview就是tabbar,在没有隐藏的情况下,点击才有效
                if self.bounds.contains(myPoint) && subView.tag == plusBtnTag && subView.superview?.isHidden == false {
                    return subView
                }
            }
        }
        return view
    }
    
}

2.BaseTabBarController.swift(继承自UITabBarController):

override func viewDidLoad() {
        super.viewDidLoad()

        //...创建所有子控制器并设置title

        //设置自定义tabbar
        let customTabBar = BaseCustomTabBar()
        self.setValue(customTabBar, forKeyPath: "tabBar")
    }
  • 遇到的问题:
    1、TabBar不回默认选择第0个item问题:
    原因:
    (1)用自定义的TabBar替换了系统的Tabbar,
    (2)在设置控制器的时候用的是 self.viewControllers = vcArr
    解决:
    在设置子控制器的的时候用 self.addChildViewController() 方法就可以了。
    2、子视图超出父视图范围,无法响应点击事件的问题:
    解决:
    重写父视图的 func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? 方法。
    3、push出一个vc(当tabbar隐藏的情况下),点击plusBtn区域,竟然还能点击成功?这是为什么?
    解决:
    定位subview是否是plusBtn,判断当前subview所在的superView是否隐藏,如果隐藏,不能点击。

你可能感兴趣的:(UITabBar自定义)