如何防止UINavigationItem的TitleView出现闪烁问题
这个问题我之前踩过坑,大概率是因为重复创建/赋值titleView,或者设置时机和导航栏过渡动画冲突导致的。给你几个亲测有效的解决思路:
1. 用懒加载确保titleView只初始化一次
别在viewWillAppear甚至每次视图出现时都new一个新的自定义视图,用懒加载让整个ViewController生命周期里只有一个titleView实例:
lazy var customTitleView: UIView = { let view = UIView(frame: CGRect(x: 0, y: 0, width: 120, height: 44)) // 这里添加你的自定义内容,比如标签、图片等 let titleLabel = UILabel(frame: view.bounds) titleLabel.text = "我的自定义标题" titleLabel.textAlignment = .center view.addSubview(titleLabel) return view }()
然后只在viewDidLoad里赋值一次:
override func viewDidLoad() { super.viewDidLoad() navigationItem.titleView = customTitleView }
这样就不会因为重复创建视图导致过渡时的闪烁。
2. 动态更新内容,不要重新赋值titleView
如果需要修改titleView的内容(比如切换页面时更新标题文字),直接修改已有的自定义视图的子控件就行,别重新给navigationItem.titleView赋值:
// 示例:更新标题文字 if let titleLabel = customTitleView.subviews.first as? UILabel { titleLabel.text = "新的标题内容" }
很多人会在viewWillAppear里重新赋值titleView,这个时机刚好和导航栏的过渡动画重叠,很容易引发闪烁。
3. 应急方案:禁用push动画(不推荐)
如果上面的方法都没解决,迫不得已可以关闭push时的动画,但这会牺牲过渡体验,尽量不用:
navigationController?.pushViewController(nextVC, animated: false)
4. 进阶:自定义导航栏过渡动画
如果需要更精细的控制,可以实现UINavigationControllerDelegate的动画代理方法,让titleView的动画和导航栏过渡同步。不过这个方案比较复杂,适合有自定义过渡需求的场景,一般前两个方法就够解决问题了。
内容的提问来源于stack exchange,提问作者Max Adamyan
相关产品推荐
相关产品推荐

