Swift:为导航控制器添加GradientLoadingBar无显示问题排查
问题分析与解决办法
你当前代码的问题
- 未设置布局约束:直接把加载条视图加到导航栏后,没有配置约束,导致加载条的frame可能是(0,0,0,0)或者位置偏移,自然无法显示
- 导航栏裁剪限制:导航栏默认
clipsToBounds = true,如果加载条超出导航栏范围会被自动裁剪 - 层级覆盖问题:导航栏内部有系统自带的视图层级,直接添加的加载条可能被系统视图遮挡
修复步骤(附代码)
第一步:正确将加载条嵌入导航栏
不要直接添加视图后放任不管,需要配置约束并调整层级:
import GradientLoadingBar class ViewController: UIViewController { private let gradientLoadingBar = GradientLoadingBar() override func viewDidLoad() { super.viewDidLoad() setupLoadingBarInNavBar() gradientLoadingBar.fadeIn() } private func setupLoadingBarInNavBar() { guard let navBar = navigationController?.navigationBar else { return } navBar.addSubview(gradientLoadingBar.gradientActivityIndicatorView) navBar.clipsToBounds = false // 关闭裁剪,避免加载条被裁掉 // 关闭自动布局转换,手动设置约束 gradientLoadingBar.gradientActivityIndicatorView.translatesAutoresizingMaskIntoConstraints = false NSLayoutConstraint.activate([ // 顶部对齐导航栏顶部(适配刘海屏),左右贴边,高度用库的默认值 gradientLoadingBar.gradientActivityIndicatorView.topAnchor.constraint(equalTo: navBar.topAnchor), gradientLoadingBar.gradientActivityIndicatorView.leadingAnchor.constraint(equalTo: navBar.leadingAnchor), gradientLoadingBar.gradientActivityIndicatorView.trailingAnchor.constraint(equalTo: navBar.trailingAnchor), gradientLoadingBar.gradientActivityIndicatorView.heightAnchor.constraint(equalToConstant: gradientLoadingBar.height) ]) // 把加载条放到最上层,防止被导航栏内容遮挡 navBar.bringSubviewToFront(gradientLoadingBar.gradientActivityIndicatorView) } }
第二步:实现全局调用的开关功能
要全局控制,把加载条做成单例并封装工具类:
// 全局加载条管理类 class GlobalLoadingBar { static let shared = GradientLoadingBar() // 全局显示方法,可指定导航栏 static func show(in navController: UINavigationController? = nil) { if let navBar = navController?.navigationBar { setupLoadingBar(in: navBar) } shared.fadeIn() } // 全局隐藏方法 static func hide() { shared.fadeOut() } private static func setupLoadingBar(in navBar: UINavigationBar) { // 先移除旧视图,避免重复添加 shared.gradientActivityIndicatorView.removeFromSuperview() navBar.addSubview(shared.gradientActivityIndicatorView) navBar.clipsToBounds = false shared.gradientActivityIndicatorView.translatesAutoresizingMaskIntoConstraints = false NSLayoutConstraint.activate([ shared.gradientActivityIndicatorView.topAnchor.constraint(equalTo: navBar.topAnchor), shared.gradientActivityIndicatorView.leadingAnchor.constraint(equalTo: navBar.leadingAnchor), shared.gradientActivityIndicatorView.trailingAnchor.constraint(equalTo: navBar.trailingAnchor), shared.gradientActivityIndicatorView.heightAnchor.constraint(equalToConstant: shared.height) ]) navBar.bringSubviewToFront(shared.gradientActivityIndicatorView) } }
全局调用示例
在任何页面直接调用即可:
// 显示加载条(传入当前导航控制器,指定加载条位置) GlobalLoadingBar.show(in: self.navigationController) // 隐藏加载条 GlobalLoadingBar.hide()
额外注意事项
- 如果导航栏是透明或自定义样式,可通过
GradientLoadingBar的gradientColors属性调整加载条颜色,避免和背景融合 - 页面跳转时,若需要加载条跟随当前导航栏,可在跳转前重新调用
show(in:)方法指定目标导航栏
内容的提问来源于stack exchange,提问作者Christian W
相关产品推荐
相关产品推荐

