Удалить 1px строку в верхней части UISearchController в больших заголовках UINavigationBar
Я перехожу из вида с большим стилем UINavigationItem
в вид, который имеет большой стиль UINavigationItem
и UISearchController
, Я настроил цвет фона UINavigationBar
,
По какой-то причине между 1 UINavigationBar
и UISearchController
, Я могу сказать, что это из NavigationBar
, потому что, если я прокручиваю строку поиска до вершины, строка исчезает. Я просто не уверен, что генерирует эту линию. Я не использую тени или что-то необычное, кроме установки barTintColor
и tintColor
, Если я не использую большие названия стилей, я вижу линию, но только при переходе между представлениями. Это как при переходе UISearchController
просто не прилипает к UINavigationBar
,
Любая помощь в выяснении, откуда эта линия идет, приветствуется.
Обновление: По некоторым дальнейшим исследованиям, кажется, что это происходит только тогда, когда navigationItem.hidesSearchBarWhenScrolling
установлен в false
, Если он изначально скрыт, то анимация из предыдущего представления будет плавной, и показ полосы также будет плавным.
4 ответа
Тестируя элемент навигации и настройки панели поиска, которые вы описали, я мог воспроизводить только линию 1px/point во время анимации перехода.
Обходной путь: Эта строка на самом деле является фоновым представлением макета (forLastBaselineLayout
) использован UINavigationBar
в конечном итоге видимый из-за глючного обрамления UISearchBar
, Установите его фон в соответствии с цветом панели навигации, чтобы скрыть его на заднем сайте.
// MARK: UINavigationControllerDelegate
public func navigationController(_ navigationController: UINavigationController, willShow viewController: UIViewController, animated: Bool) {
viewController.navigationController?.navigationBar
.forLastBaselineLayout.backgroundColor = .red // TODO:
}
Обязательно установите объект, реализующий UINavigationControllerDelegate
устанавливается как navigationController.delegate
чтобы получить вышеупомянутый вызов делегата.
Кроме того (не часть вопроса): UISearchBar
Кажется, ведет себя странно при переходе (push и pop) между контроллерами, особенно когда есть / показать searchBar
но не другой. Временное решение: визуально было приятнее временно скрыть панель поиска от представления контроллеров. Вот код, который я использую:
public func navigationController(_ navigationController: UINavigationController, willShow viewController: UIViewController, animated: Bool) {
if let sender = navigationStack.popLast() {
prepareSearchBarForTransition(from: sender)
}
navigationStack = navigationController.children
}
/// Set only from `navigationController: willShow`
private var navigationStack: [UIViewController] = []
func prepareSearchBarForTransition(from sender: UIViewController) {
if #available(iOS 11.0, *) {
let searchController = sender.navigationItem.searchController
sender.navigationItem.searchController = nil
weak var weakSender = sender
let navigationTransitionDuration: TimeInterval = 0.33
DispatchQueue.main.asyncAfter(deadline: .now() + navigationTransitionDuration) {
/// Reset the search bar.
weakSender?.navigationItem.searchController = searchController
}
} else {
// TODO: Check if the above workaround is neccessary for < iOS 11
}
}
Удалить одну пиксельную линию из всего приложения.
UINavigationBar.appearance().shadowImage = UIImage()
Выше кода удалите нижнюю строку из всего приложения. если хотите удалить только для некоторых определенных контроллеров, тогда требуется управлять скрытием / показом изображения нижней панели. Для этого используйте ниже UINavigationBar
Расширение для управления скрытием показа нижней панели в одно пиксельное изображение.
extension UIView {
fileprivate var hairlineImageView: UIImageView? {
return hairlineImageView(in: self)
}
fileprivate func hairlineImageView(in view: UIView) -> UIImageView? {
if let imageView = view as? UIImageView, imageView.bounds.height <= 1.0 {
return imageView
}
for subview in view.subviews {
if let imageView = self.hairlineImageView(in: subview) {
return imageView
}
}
return nil
}
}
extension UINavigationBar {
func hideBottomHairline() {
self.hairlineImageView?.isHidden = true
}
func showBottomHairline() {
self.hairlineImageView?.isHidden = false
}
}
Чтобы управлять скрыть / показать
self.navigationController?.navigationBar.hideBottomHairline()
self.navigationController?.navigationBar.showBottomHairline()
Выше
UIView
расширение дляhairlineImageView
также может быть использован для другихUIControls
лайкUIToolBar
extension UIToolbar {
func hideBottomHairline() {
self.hairlineImageView?.isHidden = true
}
func showBottomHairline() {
self.hairlineImageView?.isHidden = false
}
}
Если вы хотите удалить строку 1px на UINavigationBar, во всем приложении вы можете использовать приведенный ниже код в AppDelegate (didFinishLaunchingWithOptions) (проверенный код)
UINavigationBar.appearance().shadowImage = UIImage()
Используйте следующий код:
navigationController?.navigationBar.shadowImage = UIImage()