swift小知识之实现悬浮Tabbar

自定义tabbar,tabbar整体悬浮状态,效果如下图:

一. 自定义TabBar

  1. 上图中背景和中间按钮都是图片,首先要把两张图片添加到自定义tabbar中:
    override init(frame: CGRect) {
            super.init(frame: frame)
            initView()
        }
        
        private func initView(){
            //添加中间按钮
            let width = 54
            let middleButton = UIImageView(frame: CGRect(x: (Int(ScreenWidth) - width) / 2, y: 0, width: width, height: width))
            middleButton.image = UIImage(named: "add")
            middleButton.isUserInteractionEnabled = true
            self .insertSubview(middleButton, at: 0)
            //添加tabbar背景
            let backgroundImage = UIImageView(frame: CGRect(x: 15, y: 26, width: ScreenWidth - 30, height: 64))
            backgroundImage.image = UIImage(named: "tabbarBg")
            backgroundImage.contentMode = .scaleAspectFill
            backgroundImage.isUserInteractionEnabled = true
            self .insertSubview(backgroundImage, at: 1)
            //为背景添加阴影
            backgroundImage.layer.shadowColor = UIColor(red: 0 / 255, green: 32 / 255, blue: 193 / 255, alpha: 1.0).cgColor
            backgroundImage.layer.shadowOpacity = 0.2
            backgroundImage.layer.shadowRadius = 5
            //去掉顶部横线
            self.backgroundImage = UIImage()
            self.shadowImage = UIImage()
        }
  2. 重新计算UITabBarButton的frame,中间的Button要区别于其余的Button,他的高度要覆盖到中间的图片
    //layoutSubviews遍历子控件寻找UITabBarButton,给UITabBarButton重新设置frame
        override func layoutSubviews() {
            super.layoutSubviews()
            let tabBarButtonW:CGFloat = (ScreenWidth - 30) / 5
            var tabBarButtonIndex:CGFloat = 0
            for child in self.subviews {     
                let childClass: AnyClass? = NSClassFromString("UITabBarButton")
                if child.isKind(of: childClass!) {         
                    let frame = CGRect(x: tabBarButtonIndex * tabBarButtonW + 15, y: 35, width: tabBarButtonW, height: 44)
                    child.frame = frame
                    if tabBarButtonIndex == 2 {
                        child.frame = CGRect(x: tabBarButtonIndex * tabBarButtonW + 15, y: 0, width: tabBarButtonW, height: 70)
                    }
                    tabBarButtonIndex = tabBarButtonIndex + 1
                }
            }
        }

二. 自定义UITabBarController
先来判断机型,不同机型底部高度不同,然后在viewDidLayoutSubviews()方法中重新设置tabbar的高度,在addChildViewControllers()方法中设置对应的Controller,title和图片,在setChildViewController方法中设置NavigationController

//底部高度
var bottomHeight:Int?
//判断机型
var iPhoneX = UIScreen.main.bounds.size.height >= 812 ? true : false
override func viewDidLoad() {
    super.viewDidLoad()
    self.setValue(MyTabbar(), forKey:"tabBar")
    self.tabBar.tintColor = UIColor(red: 34 / 255, green: 34 / 255, blue: 34 / 255, alpha: 1.0)
    addChildViewControllers()
}
//改变tabbar的位置和高度
override func viewDidLayoutSubviews() {
    if iPhoneX {
        bottomHeight = 34
    }else{
        bottomHeight = 21
    }
    var frame = self.tabBar.frame
    frame.size.height = 90
    frame.origin.y = self.view.frame.size.height - frame.size.height - CGFloat(bottomHeight!)
    self.tabBar.frame = frame
}
    
private func addChildViewControllers() {
    setChildViewController(HomeViewController(), title: "首页", imageName: "home", selectedImageName: "home_selected")
    setChildViewController(SecondViewController(), title: "市场", imageName: "market", selectedImageName: "market_selected")
    setChildViewController(ThirdViewController(), title: "", imageName: "1", selectedImageName: "1")
    setChildViewController(FourthViewController(), title: "消息", imageName: "news", selectedImageName: "news_selected")
    setChildViewController(FiftyViewController(), title: "我的", imageName: "my", selectedImageName: "my_selected")
}  
private func setChildViewController(_ childController:UIViewController, title:String, imageName:String, selectedImageName:String){
    childController.title = title
    childController.tabBarItem.image = UIImage(named: imageName)
    childController.tabBarItem.selectedImage = UIImage(named: selectedImageName)
    let nav = UINavigationController(rootViewController: childController)
    self.addChild(nav)
}

三. 使用
在SceneDelegate文件中调用即可

func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
    window?.frame = UIScreen.main.bounds
    window?.makeKeyAndVisible()
    window?.rootViewController = MyTabbarViewController()
    guard let _ = (scene as? UIWindowScene) else { return }
}

posted on 2022-08-27 17:40  梁飞宇  阅读(939)  评论(0)    收藏  举报