如何使用 UISearchController 移除 UINavigationBar 下方的阴影

Posted

技术标签:

【中文标题】如何使用 UISearchController 移除 UINavigationBar 下方的阴影【英文标题】:How to remove shadow below UINavigationBar with UISearchController 【发布时间】:2018-01-08 11:47:32 【问题描述】:

我可以通过以下代码成功移除导航栏下方的阴影。

self.navigationController?.navigationBar.shadowImage = UIImage()

然而,当我添加一个搜索控制器时,阴影又出现了。

self.navigationItem.searchController = UISearchController(searchResultsController: nil)

我尝试了以下操作,但结果出现意外行为。

self.navigationController?.navigationBar.setBackgroundImage(UIImage(), for: .default)
self.navigationController?.navigationBar.barTintColor = .white
self.navigationController?.navigationBar.isTranslucent = false

当连接了搜索控制器时,如何去除导航栏下的阴影?

【问题讨论】:

试试self.navigationItem.searchController?.navigationController?.navigationBar.shadowImage = UIImage() @ReinierMelian 谢谢,但不幸的是,它没有用。 很多人都有这个问题forums.developer.apple.com/thread/86828 【参考方案1】:

我也没有找到好的解决办法……

现在我会这样隐藏它:

override func viewDidAppear(_ animated: Bool) 
        super.viewDidAppear(animated)
        if let imageView = navigationItem.searchController?.searchBar.superview?.subviews.first?.subviews.first as? UIImageView 
            imageView.isHidden = true
        
    

【讨论】:

我喜欢苹果的这种东西)【参考方案2】:

这是我使用的解决方案

    创建一个扩展 UINavigationController 实例的单独类,我们称之为 BaseNavigationController。这是为您准备的课程

    如果您使用情节提要,请将 BaseNavigationController 分配给情节提要中的 UINavigationController 场景

    如果您通过代码初始化导航控制器,例如:UINavigationController.init(rootViewController: someViewControllerInstance),那么只需使用BaseNavigationController.init(rootViewController: someViewControllerInstance)

该类的示例如下所示:

open class BaseNavigationController:UINavigationController 

    override open func viewDidLoad() 
        super.viewDidLoad()
        setNavigationBar()
        setNavBarBorder(false)
    

    func setNavigationBar(color:UIColor?=UIColor.white, tint:UIColor?=UIColor.darkGray)
        let appearance = UIBarButtonItem.appearance()
        appearance.setBackButtonTitlePositionAdjustment(UIOffset.init(horizontal: 0.0, vertical: 0), for: .default)
        self.navigationBar.barTintColor = color!
        self.navigationBar.isTranslucent = false
        self.navigationBar.tintColor = tint!
        self.navigationBar.titleTextAttributes = [ NSAttributedString.Key.foregroundColor: tint! ]
    

    func setTitleColor(_ color:UIColor?=UIColor.darkGray)

    

    func setNavBarBorder(_ enable:Bool) 
        self.navigationBar.setBackgroundImage((enable ? nil : UIImage()), for: UIBarMetrics.default)
        self.navigationBar.shadowImage = (enable ? nil : UIImage())
        self.navigationBar.setValue(true, forKey: "hidesShadow")
    


现在,有趣的部分是,如果您正在处理模棱两可的布局,您可能需要在 viewWillLayoutSubviews 中执行此操作,否则将这段代码放入 viewWillAppear viewController 实例。

(self.navigationController as? BaseNavigationController)?. setNavBarBorder(false)

对于某些 ios 版本,有趣的代码位于 self.navigationBar.setValue(true, forKey: "hidesShadow")

【讨论】:

【参考方案3】:

您可以改为将 searchBar 添加到 storyBoard 中的 viewController 并将其 Search Style 属性设置为 Minimal,它看起来像这样:

【讨论】:

可悲的是,您使用这种方法从 UISearchController 中丢失了很多东西 :(【参考方案4】:

我对这个问题的一点贡献。当然,这不是正确的方法,但它适用于不透明的导航栏。这个想法是在这个阴影之上添加一个视图。

let searchBar = searchController.searchBar
let maskView = UIView(frame: .zero)
maskView.backgroundColor = .white // or any color you want
searchBar.addSubview(maskView)

//We need to use constraint so the mask view follow the search bar animation
maskView.translatesAutoresizingMaskIntoConstraints = false
let views = ["maskView": maskView]
searchBar.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|-(0)-[maskView]-(0)-|",
                                                        options: NSLayoutConstraint.FormatOptions.alignAllCenterY,
                                                        metrics: nil,
                                                        views: views))
searchBar.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:[maskView(1)]-(-1)-|",
                                                        options: NSLayoutConstraint.FormatOptions.alignAllCenterX,
                                                        metrics: nil,
                                                        views: views))

【讨论】:

以上是关于如何使用 UISearchController 移除 UINavigationBar 下方的阴影的主要内容,如果未能解决你的问题,请参考以下文章

如何同时使用 NSFetchedResultsController 和 UISearchController?

如何让 UISearchController 与 UISearchBar Interface Builder 控件一起使用?

如何下移 UISearchController?

使用 UISearchController 时如何删除排序/过滤的项目

如何使用 UISearchController 使导航栏保持可见?

你如何使用 Storyboards 引用 UISearchController