Как удалить тень под UINavigationBar с помощью UISearchController

Image 1

Я мог бы успешно удалить тень под панелью навигации со следующей строкой кода.

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

Image 2

Однако когда я добавил контроллер поиска, тень снова появилась.

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

Image 3

Я попробовал следующее, но в результате получил неожиданное поведение.

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

Image 4

Как убрать тень под панелью навигации, когда подключен поисковый контроллер?

Ответ 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

Вот решение, которое я использую

  1. Создайте отдельный класс, расширяющий экземпляр UINavigationController, назовем его BaseNavigationController. Здесь ваш класс для вас

  2. Если вы используете раскадровки, назначьте BaseNavigationController вашей сцене UINavigationController в раскадровке

  3. Если вы инициализируете контроллер навигации с помощью кода, например: 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)

интересный фрагмент кода находится в self.navigationBar.setValue(true, forKey: "hidesShadow"), для некоторых версий iOS.

Ответ 3

Вместо этого вы можете добавить searchBar в свой viewController в storyBoard и установить для его свойства Search Style значение Minimal, и оно будет выглядеть следующим образом:

enter image description here

Ответ 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))