Удалить 1px строку в верхней части UISearchController в больших заголовках UINavigationBar - PullRequest
0 голосов
/ 15 сентября 2018

Я перехожу из вида с большим стилем UINavigationItem в вид с большим стилем UINavigationItem и UISearchController.Я настроил цвет фона для UINavigationBar.

. По какой-то причине между UINavigationBar и UISearchController есть строка размером 1 пиксель или пробел.Я могу сказать, что это от NavigationBar, потому что, если я прокручиваю так, что строка поиска остается наверху, строка исчезает.Я просто не уверен, что генерирует эту линию.Я не использую тени или что-то необычное, кроме установки barTintColor и tintColor.Если я не использую большие заголовки стилей, я вижу линию, но только при переходе между представлениями.Это похоже на то, что при переходе UISearchController просто не придерживается UINavigationBar.

Любая помощь в выяснении, откуда идет эта строка, приветствуется.

Обновление: на некоторыхДальнейшее расследование, кажется, это происходит только тогда, когда navigationItem.hidesSearchBarWhenScrolling установлен на false.Если он изначально скрыт, то анимация из предыдущего представления будет плавной, а полоса также будет плавной.

Example screenshot of line

Ответы [ 4 ]

0 голосов
/ 21 сентября 2018

Тестируя элемент навигации и настройки панели поиска, которые вы описали, я мог воспроизвести только линию 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
    }
}
0 голосов
/ 18 сентября 2018

Если вы хотите удалить строку 1px на UINavigationBar, во всем приложении вы можете использовать приведенный ниже код в AppDelegate (didFinishLaunchingWithOptions) (проверенный код)

UINavigationBar.appearance().shadowImage = UIImage()
0 голосов
/ 18 сентября 2018

Чтобы удалить одну строку пикселя из всего приложения.

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
    }
}
0 голосов
/ 18 сентября 2018

Используйте следующий код:

navigationController?.navigationBar.shadowImage = UIImage()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...