CustomTabbarViewController:创建并管理带动态圆形高亮的自定义Tab Bar界面
自定义TabBar控制器(CustomTabbarViewController)
CustomTabbarViewController 是UITabBarController的自定义子类,专为iOS应用打造定制化且视觉美观的Tab Bar界面。它负责管理多个与Tab项绑定的视图控制器的展示,同时支持Tab Bar外观与行为的定制。
核心特性
- 自定义Tab Bar外观:可定制背景色、色调(tint color)和圆角半径。
- 动态圆形高亮指示器:选中Tab项时,圆形指示器会动画移动到对应位置,为用户提供清晰的视觉反馈,提升交互体验。
- 自适应布局:Tab Bar会自动调整布局,适配设备方向变化和安全区域内边距,确保在不同设备、不同方向下都能呈现一致美观的效果。
完整实现代码
import UIKit class TabbarViewController: UITabBarController { var circle: UIView? override func viewDidAppear(_ animated: Bool) { super.viewDidAppear(animated) guard let selectedItem = tabBar.selectedItem, let index = tabBar.items?.firstIndex(of: selectedItem) else { return } let frame = frameForTabAtIndex(index: index) circle?.center.x = frame.origin.x + frame.width/2 circle?.center.y = frame.origin.y + frame.height/2 circle?.alpha = 1 } override func viewDidLoad() { super.viewDidLoad() self.navigationController?.setNavigationBarHidden(true, animated: false) self.setupTabBarUI() guard let itemCount = tabBar.items?.count else { return } let numberOfItems = CGFloat(itemCount) let tabBarItemSize = CGSize(width: (tabBar.frame.width / numberOfItems) - 20, height: tabBar.frame.height) circle = UIView(frame: CGRect(x: 0, y: 0, width: tabBarItemSize.height, height: tabBarItemSize.height)) circle?.backgroundColor = #colorLiteral(red: 0.2770082951, green: 0.5475645661, blue: 0, alpha: 0.28) circle?.layer.cornerRadius = circle!.frame.width/2 circle?.alpha = 0 tabBar.addSubview(circle!) tabBar.sendSubviewToBack(circle!) } override func viewDidLayoutSubviews() { super.viewDidLayoutSubviews() self.setupCustomTabBarFrame() } } extension TabbarViewController { // MARK: 私有方法 private func setupCustomTabBarFrame() { let height = self.view.safeAreaInsets.bottom + 64 var tabFrame = self.tabBar.frame tabFrame.size.height = height tabFrame.origin.y = self.view.frame.size.height - height self.tabBar.frame = tabFrame self.tabBar.setNeedsLayout() self.tabBar.layoutIfNeeded() } private func setupTabBarUI() { // 设置颜色和圆角 self.tabBar.layer.cornerRadius = 22 self.tabBar.layer.masksToBounds = true self.tabBar.layer.maskedCorners = [.layerMinXMinYCorner, .layerMaxXMinYCorner] self.tabBar.backgroundColor = UIColor(red: 245/255, green: 246/255, blue: 247/255, alpha: 1) self.tabBar.tintColor = #colorLiteral(red: 0.4670000076, green: 0.6430000067, blue: 0.3919999897, alpha: 1) // self.tabBar.unselectedItemTintColor = UIColor.green // 移除底部分割线 if #available(iOS 13.0, *) { let appearance = self.tabBar.standardAppearance appearance.shadowImage = nil appearance.shadowColor = nil self.tabBar.standardAppearance = appearance } else { self.tabBar.shadowImage = UIImage() self.tabBar.backgroundImage = UIImage() } } func frameForTabAtIndex(index: Int) -> CGRect { var frames = tabBar.subviews.compactMap { (view:UIView) -> CGRect? in if let controlView = view as? UIControl { for item in controlView.subviews { if let imageView = item as? UIImageView { return imageView.superview!.convert(imageView.frame, to: tabBar) } } return controlView.frame } return nil } frames.sort { $0.origin.x < $1.origin.x } guard frames.count > index else { return frames.last ?? CGRect.zero } return frames[index] } override func tabBar(_ tabBar: UITabBar, didSelect item: UITabBarItem) { guard let index = tabBar.items?.firstIndex(of: item) else { return } let frame = frameForTabAtIndex(index: index) self.circle?.center.x = frame.origin.x + frame.width/2 self.circle?.center.y = frame.origin.y + frame.height/2 } }
效果示例

内容的提问来源于stack exchange,提问作者Hassan
相关产品推荐
相关产品推荐

