Swift中如何从其他控制器获取UITabBar高度以在其上方添加视图
问题解决方案
核心错误点
你当前的计算逻辑完全错误,状态栏高度和UITabBar的位置没有任何关联,所以拿statusBarFrame计算必然得不到正确结果。
具体解决步骤
- 第一步:获取UITabBar高度
只要你的MyController是被UITabBarController管理的子控制器,直接通过tabBarController?.tabBar.bounds.height就可以拿到正确的tabBar高度,这个高度已经包含了全面屏底部的安全区域高度,不需要额外单独计算安全区。 - 第二步:修正坐标计算逻辑
自定义视图要在tabBar正上方,y坐标的计算规则为:父控件高度 - tabBar高度 - 自定义视图高度 - 第三步:优化视图添加逻辑
你当前直接将视图添加到window上,会导致全局悬浮,如果你只需要在MyController显示的时候展示,建议添加到当前控制器的view上即可,避免其他页面也出现这个视图。
修正后的代码示例
硬算frame版本
let timerView = UINib(nibName: "WorkoutTimer", bundle: nil).instantiate(withOwner: nil, options: nil).first as? WorkoutTimer if let timerView = timerView, let tabBar = tabBarController?.tabBar { let screenWidth = UIScreen.main.bounds.width // 直接获取tabBar高度 let tabBarHeight = tabBar.bounds.height // 计算y坐标:屏幕高度 - tabBar高度 - 自定义视图高度50 let yPosition = UIScreen.main.bounds.height - tabBarHeight - 50 timerView.frame = CGRect(x: 0, y: yPosition, width: screenWidth, height: 50) // 如果只需要当前控制器显示,就用view.addSubview,需要全局显示再用window view.addSubview(timerView) // 全局显示用下面这行替换上面的addSubview // UIApplication.shared.windows.first?.addSubview(timerView) }
自动布局版本(更推荐,适配横竖屏、不同设备尺寸更稳定)
let timerView = UINib(nibName: "WorkoutTimer", bundle: nil).instantiate(withOwner: nil, options: nil).first as? WorkoutTimer if let timerView = timerView, let tabBar = tabBarController?.tabBar { timerView.translatesAutoresizingMaskIntoConstraints = false view.addSubview(timerView) NSLayoutConstraint.activate([ timerView.leadingAnchor.constraint(equalTo: view.leadingAnchor), timerView.trailingAnchor.constraint(equalTo: view.trailingAnchor), timerView.heightAnchor.constraint(equalToConstant: 50), // 直接约束在tabBar的顶部,完全不用计算坐标 timerView.bottomAnchor.constraint(equalTo: tabBar.topAnchor) ]) }
注意事项
- 如果你确实需要将视图添加到window上做全局展示,只需要将约束的父控件换成window即可,底部约束改为约束到tabBar的顶部就行,不需要硬算坐标。
- 记得在MyController销毁、或者不需要展示timerView的时候调用
timerView.removeFromSuperview()移除视图,避免内存泄漏。
内容的提问来源于stack exchange,提问作者user10469417
相关产品推荐
相关产品推荐

