iOS 11搜索栏动画Bug:导航跳转时自定义样式短暂显示白色背景
解决UISearchController导航跳转时搜索栏闪白的问题
我之前也碰到过这个一模一样的烦人的坑!导航跳转到目标控制器时,自定义样式的搜索栏在过渡动画里突然闪白,你调试视图层级看到的白色背景,大概率是系统在动画过程中临时加载的默认背景视图搞的鬼。下面是几个亲测有效的解决方法:
方法一:彻底自定义UISearchBar的背景
创建一个自定义的UISearchBar子类,直接移除所有默认背景视图,替换成你想要的自定义样式:
class CustomSearchBar: UISearchBar { override func awakeFromNib() { super.awakeFromNib() setupCustomStyle() } override init(frame: CGRect) { super.init(frame: frame) setupCustomStyle() } required init?(coder: NSCoder) { super.init(coder: coder) setupCustomStyle() } private func setupCustomStyle() { // 清空默认背景图 self.backgroundImage = UIImage() // 设置搜索输入框的背景色 self.searchTextField.backgroundColor = .yourCustomBackgroundColor // 遍历子视图,隐藏系统自带的背景ImageView for subview in self.subviews.first?.subviews ?? [] { if subview is UIImageView { subview.isHidden = true } } } }
之后用这个自定义类替换你原来的UISearchBar,再关联到UISearchController上即可。
方法二:在视图生命周期里强制锁定样式
有时候系统会在导航过渡前悄悄重置搜索栏的样式,你可以在viewWillAppear(_:)里强制重新应用自定义样式,甚至用performWithoutAnimation避免系统默认动画的干扰:
override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) UIView.performWithoutAnimation { // 重新设置搜索栏核心样式 searchController.searchBar.searchTextField.backgroundColor = .yourCustomBackgroundColor searchController.searchBar.backgroundImage = UIImage() // 刷新导航项,确保样式立即生效 navigationItem.searchController = searchController navigationItem.hidesSearchBarWhenScrolling = false // 根据你的需求调整 } }
方法三:统一导航栏的过渡样式
如果你的导航栏本身也有自定义背景色,可能在过渡动画时和搜索栏的样式产生冲突。可以设置导航栏的standardAppearance和scrollEdgeAppearance,确保过渡期间样式完全一致:
let navAppearance = UINavigationBarAppearance() navAppearance.backgroundColor = .yourNavigationBarColor // 和搜索栏背景色匹配或协调 navAppearance.shadowColor = .clear // 去掉导航栏底部阴影,避免过渡时的视觉断层 navigationController?.navigationBar.standardAppearance = navAppearance navigationController?.navigationBar.scrollEdgeAppearance = navAppearance navigationController?.navigationBar.compactAppearance = navAppearance
额外调试小技巧
如果还是没解决,你可以在Xcode的Debug View Hierarchy里,暂停在闪白的瞬间,仔细查看白色背景视图的类名:
- 如果是
UIBarBackground,那就是导航栏的背景过渡问题,用方法三解决; - 如果是
UISearchBar内部的UIImageView,那就是方法一里没处理干净,再遍历子视图找到它并隐藏或设置颜色。
内容的提问来源于stack exchange,提问作者frangulyan
相关产品推荐
相关产品推荐

