You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Swift 4中如何获取Tab Bar图标的CGRect定位?

获取Swift 4中Tab Bar指定图标的精确CGRect方案

嘿,我来帮你搞定这个问题!要实现向Tab Bar指定图标收缩的「基因」特效,关键就是拿到图标的准确坐标和尺寸,我给你两个靠谱的实现思路,完全适配Swift 4环境:

方法一:通过TabBarButton的子视图直接获取图标帧

系统默认的Tab Bar里,每个TabBarItem对应一个UITabBarButton控件,而图标就嵌套在这个button的子视图里。你可以通过遍历子视图的方式定位到目标图标,步骤如下:

  1. 获取当前TabBarController的tabBar实例;
  2. 筛选出tabBar下所有类型为UIControl的子视图(也就是UITabBarButton);
  3. 根据目标图标的索引,找到对应的UITabBarButton;
  4. 在这个button的子视图里找到UIImageView类型的视图(这就是承载图标的容器);
  5. 把图标的本地frame转换为你需要的坐标系(比如全局window坐标,或者当前控制器view的坐标)。

代码示例

// 假设你要获取索引为1的TabBar图标(索引从0开始)
let targetIndex = 1

guard let tabBar = tabBarController?.tabBar else { return }
// 筛选出所有UITabBarButton
let tabBarButtons = tabBar.subviews.filter { $0 is UIControl }

guard targetIndex < tabBarButtons.count else {
    print("目标索引超出TabBarItem数量")
    return
}

let targetButton = tabBarButtons[targetIndex]
// 找到图标对应的UIImageView
if let iconImageView = targetButton.subviews.first(where: { $0 is UIImageView }) {
    // 转换为全局window坐标系的CGRect(动画终点常用)
    let globalIconFrame = iconImageView.convert(iconImageView.bounds, to: UIApplication.shared.keyWindow)
    print("图标全局坐标:\(globalIconFrame)")
    
    // 如果需要相对于当前控制器view的坐标,就转成view的坐标系
    let localIconFrame = iconImageView.convert(iconImageView.bounds, to: self.view)
    print("图标本地坐标:\(localIconFrame)")
}

方法二:结合TabBar的item区域定位图标

如果你不确定UITabBarButton的筛选逻辑,也可以先通过TabBar的rect(for:)方法获取目标TabBarItem的整体区域,再缩小范围找到图标视图:

代码示例

let targetIndex = 1

guard let tabBar = tabBarController?.tabBar,
      let targetItem = tabBar.items?[targetIndex] else { return }

// 获取目标TabBarItem的整体区域(相对于tabBar)
let itemTotalRect = tabBar.rect(for: targetItem)
// 找到与该区域重叠的UITabBarButton
let targetButton = tabBar.subviews.first(where: {
    $0.frame.intersects(itemTotalRect) && $0 is UIControl
})

if let button = targetButton,
   let iconImageView = button.subviews.first(where: { $0 is UIImageView }) {
    let globalFrame = iconImageView.convert(iconImageView.bounds, to: UIApplication.shared.keyWindow)
    // 这里拿到的globalFrame就是你需要的动画终点坐标啦
}

注意事项

  • 布局时机:一定要在视图完成布局后再获取frame,比如在viewDidAppear(_:)方法里调用代码,不要在viewDidLoad里(此时视图还未完成渲染,frame可能不准确);
  • 兼容性:以上方法针对系统默认TabBar有效,如果是自定义TabBar,你需要根据自己的自定义结构调整子视图的筛选逻辑;
  • 坐标系转换:根据动画的需求选择合适的坐标系,全局window坐标适用于跨视图的动画,本地view坐标适用于当前控制器内的动画。

内容的提问来源于stack exchange,提问作者Yahav

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 08:48:05