初学swift5 实现简易自定义tababar

本文是刚学习swift后,第一个练手的项目,主要目的是将学到的swift知识去完成一个简易的自定义tabbar

先看效果


总效果图

然后我们在一层一层看

根据自己的需求,用CGContext 画的背景图
中间的tabBarItem不设置图片,只设置文字
在tabbar上的背景图上插入自定义的控件
这里自定义的控件是button

到这里,总结下就是,
我们自定义的tabbar,根据需求添加一个背景图,然后在插入我们自定义的控件到正确的位置上即可,其他的都沿用原生的tabbar,因为自定义控件会挡住原生tabbaritem,所以需要单独为我们自定义的控件添加点击事件(后面会讲道自定义控件的点击事件)。

代码:

class CustomTabbar: UITabBar {
    private lazy var centerBtn: UIButton = {
        let btn = UIButton.init(type: .custom)
        btn.setImage(UIImage.initWithOriginalMode(named: "tab_diy"), for: .normal)
        btn.setImage(UIImage.initWithOriginalMode(named: "tab_diy_sel"), for: .selected)
        btn.sizeToFit()
        btn.imageEdgeInsets = UIEdgeInsets.init(top: -10, left: 0, bottom: 0, right: 0)
        btn.addTarget(self, action: #selector(clickAtItem), for: .touchUpInside)
        return btn
    }()
    weak open var clickDelegate: CustomTabbarDelegate?

   ...

    override init(frame: CGRect) {
        super.init(frame: frame)
        //   添加背景图
        let backV = UIImageView.init(frame: CGRect.init(x: 0, y: -26, width: ScreenW, height: 75))
        backV.backgroundColor = UIColor.clear
        self.addSubview(backV)

        // 自己绘制的背景图
        let img = drawCustomTabbarBackImg()
        backV.image = img

        // 添加自定义的btn控件
        self.addSubview(centerBtn)
    }

    override func layoutSubviews() {
        super.layoutSubviews()
        // 重新计算自定义btn控件的位置
        centerBtn.frame = CGRect.init(x: ScreenW/5*2, y: -26, width: ScreenW/5, height: 75)
        self.bringSubviewToFront(centerBtn)
    }


    @objc func clickAtItem(btn: UIButton) {
        // btn 点击之后状态给反转下
        btn.isSelected = !btn.isSelected
        // 让代理去实现点击事件。
        clickDelegate?.clickTabbarItem((self, centerBtn))
    }

## 重写hitTest方法,去监听中间按钮点击,目的是为了让凸出的部分点 击也有反应 ##
## 当然你的视图不超出父视图,这个也可以不写 ##

    override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
        if !self.isHidden, centerBtn.frame.contains(point) {
            return centerBtn
        }
        // 记得把centerbtn 设置成 nomal状态
        centerBtn.isSelected = false
        return super.hitTest(point, with: event)
    }
}
}}

有一个代理的注意点,(毕竟初学swift,还是有必要提一下)

## OC 中代理都是用 weak 修饰 防止循环引用,这里也要遵守 ##
weak open var clickDelegate: CustomTabbarDelegate?

@objc func clickAtItem(btn: UIButton) {
        // btn 点击之后状态给反转下
        btn.isSelected = !btn.isSelected
        // 让代理去实现点击事件。
        clickDelegate?.clickTabbarItem((self, centerBtn))
    }

## :后面的 class,指定只能给class用不能给值类型用 ##
protocol CustomTabbarDelegate: class {
    func clickTabbarItem(_: (Any));
}

接下来就是 tabbarController 里面替换成我们自定义的tabbar了
关键一句就是:

self.setValue(customTab, forKey: "tabBar")
class BaseTabVC: UITabBarController {

    override func viewDidLoad() {
        super.viewDidLoad()
        self.customTabbar()

        let temple = (titles: ["首页", "分类", "DIY", "圈子", "我的"], images: ["tab_home", "tab_material", "", "tab_social", "tab_my"])
        let vcs = [HomeVC.init(), MaterialVC.init(), DIYVC.init(), SocialVC.init(), ProfileVC.init()].enumerated().map { (idx, vc) -> UIViewController in
            self.controller(createTabbarItemWith: vc, title: temple.titles[idx], image: temple.images[idx])
            let nav = BaseNavVC.init(rootViewController: vc)
            return nav
        }

        self.viewControllers = vcs
    }

    func customTabbar() {
        let customTab = CustomTabbar.init(frame: CGRect.init(x: 0, y: ScreenH - TabbarH, width: ScreenW, height: TabbarH))
        // 别忘了实现代理
        customTab.clickDelegate = self
        self.setValue(customTab, forKey: "tabBar")

## 这里还是我们熟悉的调整tabbar 上面的一些属性 ##
## 根据我们的需求调整就行 ##

        //调整tabbar 上面横线阴影颜色
        self.tabBar.backgroundImage = UIImage.init()
        self.tabBar.shadowImage = UIImage.init();
        self.tabBar.barTintColor = HEX(hexValue: 0xFFFFFF)
        self.tabBar.tintColor = HEX(hexValue: 0x0D57F6)
        self.tabBar.unselectedItemTintColor = HEX(hexValue: 0x000000)
        self.tabBar.isTranslucent = false
    }
    ...

切换tabBarItem的方法

self.selectedIndex = 2
// 扩展里面, 实现 点击 customTabbar 的代理
extension BaseTabVC: CustomTabbarDelegate {
    func clickTabbarItem(_: (Any)) {
        guard let vc = self.viewControllers?[2] else { return }
## 切换当前tabitem 到我们需要的控制器 ##
        self.selectedIndex = 2
    }
}

写在最后,实现自定义的tabbar 可以有很多种思路,复杂的可以写一个view 替换掉tabbar,然后将系统的tabbar 给隐藏掉,都是可以的,只不过需要实现tabbar所有的功能,会比较繁琐。这个自定义的好处是,整体代码量不多,思路实现也不复杂,主要是不影响原生tabbar的功能。

你可能感兴趣的:(初学swift5 实现简易自定义tababar)