Swift中为UITabBarItem添加顶部圆形选中指示器的问题求助
解决UITabBarItem顶部圆形选中指示器问题
你之前的方案行不通,是因为selectionIndicatorImage是作为UITabBar的子视图存在的,而UITabBar默认开启了clipsToBounds属性,你把圆形的Y坐标设为-2,会被TabBar的可视区域裁剪掉,所以看不到。
换个思路,直接在TabBar上方添加一个自定义的圆形View,通过监听TabBar的选中事件来移动这个指示器,具体实现如下:
步骤1:自定义TabBarController(或在当前控制器中实现)
如果你的项目用了自定义TabBarController,直接在子类中写以下代码;如果是普通ViewController,替换成self.tabBarController!相关的调用即可。
import UIKit class CustomTabBarController: UITabBarController { private var tabIndicator: UIView! override func viewDidLoad() { super.viewDidLoad() setupTabIndicator() // 初始化指示器到第一个选中的Tab位置 if let firstItem = tabBar.items?.first { updateIndicatorPosition(for: firstItem) } // 监听Tab选中变化 tabBar.addObserver(self, forKeyPath: "selectedItem", options: .new, context: nil) } // 创建圆形指示器 private func setupTabIndicator() { let indicatorSize: CGFloat = 8.0 tabIndicator = UIView() tabIndicator.backgroundColor = .red tabIndicator.layer.cornerRadius = indicatorSize / 2 tabIndicator.translatesAutoresizingMaskIntoConstraints = false view.addSubview(tabIndicator) // 添加Auto Layout约束 NSLayoutConstraint.activate([ tabIndicator.widthAnchor.constraint(equalToConstant: indicatorSize), tabIndicator.heightAnchor.constraint(equalToConstant: indicatorSize), tabIndicator.bottomAnchor.constraint(equalTo: tabBar.topAnchor, constant: -indicatorSize/2) ]) // 确保指示器在最上层 view.bringSubviewToFront(tabIndicator) } // 更新指示器位置 private func updateIndicatorPosition(for item: UITabBarItem) { guard let items = tabBar.items, let index = items.firstIndex(of: item) else { return } let itemWidth = tabBar.frame.width / CGFloat(items.count) let targetCenterX = itemWidth * CGFloat(index) + itemWidth / 2 // 添加入场动画 UIView.animate(withDuration: 0.2) { self.tabIndicator.center.x = targetCenterX } } // 监听Tab选中变化 override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) { if keyPath == "selectedItem", let selectedItem = change?[.newKey] as? UITabBarItem { updateIndicatorPosition(for: selectedItem) } } deinit { // 移除监听,避免内存泄漏 tabBar.removeObserver(self, forKeyPath: "selectedItem") } }
步骤2:替换默认TabBarController
在AppDelegate或者SceneDelegate中,把原来的TabBarController替换成自定义的CustomTabBarController即可。如果是用Storyboard,直接给TabBarController的Class设置为CustomTabBarController。
这样实现的指示器不会被TabBar裁剪,而且能跟随Tab选中状态平滑移动,适配不同屏幕尺寸和旋转场景。
内容的提问来源于stack exchange,提问作者Louiza A
相关产品推荐
相关产品推荐

