iOS 自定义TabBar Controller高度问题

Swift 复制代码
protocol CNCustomTabBarDelegate: NSObjectProtocol {
    func tabShouldSelectIndex(index: Int) -> Bool
    func tabBarDidClickAtIndex(index: Int)
    func centerButtonDidClick()
}

class CNCustomTabBar: UITabBar {
    
    static let HEIGHT: CGFloat = TAB_HEIGHT + CNScreen.safeAreaBottom

    // MARK: 不能设置小数, 否则tableView 分页滚动会有问题
    static let TAB_HEIGHT: CGFloat = 56
    
    weak var myDelegate: CNCustomTabBarDelegate?
    
    let TAG_NUM: Int = 100000
    
    var currentIndex: Int = 0 {
        willSet {
            if currentIndex >= 0 && currentIndex < CNTabItem.items.count {
                guard self.currentIndex != newValue else {
                    return
                }
                self.currentIndex = newValue
                updateTabBar()
            }
        }
    }
    
    var isDark: Bool {
        currentIndex == CNTabItem.hot.tabIndex
    }
    
    lazy var bgView: UIView = {
        let tmpView = UIView()
        tmpView.backgroundColor = .white
        return tmpView
    }()
    
    // MARK: 关键代码改变UITabBar 高度, 不重写sizeThatFits只是bgView 的高度改变
    override open func sizeThatFits(_ size: CGSize) -> CGSize {
        super.sizeThatFits(size)
        var sizeThatFits = super.sizeThatFits(size)
        sizeThatFits.height = CNCustomTabBar.HEIGHT
        return sizeThatFits
    }
    
    override init(frame: CGRect) {
        super.init(frame: .init(x: 0, y: 0, width: CNScreen.width, height: CNCustomTabBar.HEIGHT))
        setupUI()
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    override func layoutSubviews() {
        super.layoutSubviews()
        let cl: AnyClass? = NSClassFromString("UITabBarButton")
        if let cl {
            for item in subviews {
                if item.isKind(of: cl) {
                    item.removeFromSuperview()
                }
            }
        }
    }
    
    override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
        guard !self.isHidden else {
            return nil
        }
        for i in 0..<CNTabItem.items.count {
            let btn = self.bgView.viewWithTag(TAG_NUM+i)
            if let btn,  btn.bounds.contains(btn.convert(point, from: self)) && btn.isHidden == false && btn.alpha == 1 {
                return btn
            }
        }
        return nil
    }
}

extension CNCustomTabBar {
    func setupUI() {
        bgView.frame = bounds
        bgView.roundCorners([.topLeft, .topRight], radius: 16)
        addSubview(bgView)
        //去除黑线
        let tabbarAppearance = self.standardAppearance
        tabbarAppearance.backgroundEffect = nil
        tabbarAppearance.backgroundImage = UIColor.clear.toImage()
        tabbarAppearance.shadowImage = UIColor.clear.toImage()
        self.standardAppearance = tabbarAppearance
        let itemW = CNScreen.width / CGFloat(CNTabItem.items.count)
        for (i, item) in CNTabItem.items.enumerated() {
            let tabBtn = setupTabButton(tabItem: item)
            tabBtn.addTarget(self, action: #selector(tabarBtnClick), for: .touchUpInside)
            bgView.addSubview(tabBtn)
            tabBtn.frame = CGRect(x: CGFloat(i) * itemW, y: 0, width: itemW, height: Self.TAB_HEIGHT)
        }
        updateTabBar()
    }
    
    @objc func tabarBtnClick(_ button: UIButton) {
        let index = button.tag - TAG_NUM
        let isShould = myDelegate?.tabShouldSelectIndex(index: index) ?? true
        if isShould {
            myDelegate?.tabBarDidClickAtIndex(index: index)
        } else {
            
        }
    }
    
    func updateTabBar() {
        bgView.backgroundColor = isDark ? .black : .white
        for (i, tabItem) in CNTabItem.items.enumerated() {
            let isSelected = currentIndex == i
            if let btn = self.bgView.viewWithTag(TAG_NUM+i) as? UIButton {
                var updateConfig = btn.configuration
                if isSelected {
                    updateConfig?.image = UIImage(named: tabItem.selImage)
                } else {
                    updateConfig?.image = UIImage(named: tabItem.norImage(isDark: isDark))
                }
                var titleColor = UIColor.hex("#A6ABB7")!
                if isDark && isSelected {
                    titleColor = UIColor.hex("#FFDA33")!
                } else if isDark {
                    titleColor = UIColor.hex("#CCCCCC")!
                } else if isSelected {
                    titleColor = UIColor.hex("#010101")!
                }
                let titleAttributes = AttributeContainer([
                    .font: UIFont.systemFont(ofSize: 10, weight: .medium),
                    .foregroundColor: titleColor
                ])
                let title = AttributedString(tabItem.title, attributes: titleAttributes)
                updateConfig?.attributedTitle = title
                btn.configuration = updateConfig
            }
        }
    }
    

    private func setupTabButton(tabItem: CNTabItem) -> UIButton {
        let button = UIButton()
        button.tag = TAG_NUM + tabItem.tabIndex
        var config = UIButton.Configuration.plain()
        config.baseBackgroundColor = .clear
        config.background.backgroundColor = .clear
        config.image = UIImage(named: tabItem.norImage(isDark: false))
        config.imagePlacement = .top
        config.imagePadding = 3
        let titleAttributes = AttributeContainer([
            .font: UIFont.systemFont(ofSize: 10, weight: .medium),
            .foregroundColor: UIColor.hex("#A6ABB7")!
        ])
        var title = AttributedString(tabItem.title, attributes: titleAttributes)
        config.attributedTitle = title
        button.configuration = config
        button.backgroundColor = .clear
        return button
    }
}

继承自UITabBar 自定义TabBar 时,遇到两个问题:

  1. 在 tabBarController 中 setValue(self.customTabBar, forKey: "tabBar") 设置self.customTabBar 后,tabBarController 的 viewControllers 高度 为屏幕高度,正常应该为 屏幕高度 - tabBar - 底部安全区高度,在设置tabBar.isTranslucent = false 后就莫名奇妙解决了。

  2. 项目中所有的高度使用了屏幕宽度等比缩放,即 h * w_scale,使用zfplayer 时, tableView 设置isPageEnable = true分页,如果cell 高度为小数,则会出现bug, 视频画面不能正常切换。这是因为自定义 TabBar 的高度一开始使用了等比缩放 56 * w_scale,修改为整数 56 后。恢复正常

相关推荐
比奥利奥还傲.4 天前
哪吒监控面板实战:部署 Dashboard、接入 Agent、钉钉告警,再配置固定公网访问
网络·人工智能·分布式·1024程序员节
默 语6 天前
Java新手入门:从零开始安装JDK并配置环境变量
java·开发语言·python·mysql·group by·1024程序员节·数据去重
学传打活22 天前
【边打字.边学昆仑正义文化】_进阶篇5 宇宙星系的运转(续3)
微信公众平台·1024程序员节·汉字·昆仑正义文化
学传打活1 个月前
【边打字.边学昆仑正义文化】_进阶篇5 宇宙星系的运转(续1)
微信公众平台·1024程序员节·汉字·昆仑正义文化
fangzhanpeng1681 个月前
快速掌握C#语言基础知识点(1.基础数据类型)
开发语言·c#·1024程序员节
无己心1 个月前
面向多平台 AI 搜索引擎的适配层架构设计
前端·人工智能·搜索引擎·ai·1024程序员节
u0103055271 个月前
AI驱动的安卓UI自动生成功能实现
人工智能·1024程序员节
u0103055271 个月前
长株潭智能体赋能腾讯元器链接共享
1024程序员节
云贝贝贝1 个月前
OceanBase认证体系介绍与备考指南
运维·服务器·oceanbase·1024程序员节
u0103055271 个月前
Java图像处理实战指南
人工智能·1024程序员节