Как удалить тень под 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
Вот решение, которое я использую
Создайте отдельный класс, расширяющий экземпляр 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)
интересный фрагмент кода находится в 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))