在大型标题UINavigationBar中删除UISearchController顶部的1px行

Ben*_*son 9 uinavigationbar ios uisearchcontroller preferslargetitles

我正在从具有大样式UINavigationItem的视图转换为具有大样式UINavigationItem和视图的视图UISearchController.我已经定制了背景颜色UINavigationBar.

出于某种原因,在UINavigationBar和之间有1px的线或空间UISearchController.我可以告诉它NavigationBar,因为如果我滚动以便搜索栏粘在顶部,那么该线就会消失.我只是不确定是什么产生了这条线.我没有使用阴影,或任何花哨的东西,除了设置barTintColortintColor.如果我不使用大型标题,我会看到该行,但仅限于在视图之间转换时.这就像过渡时UISearchController刚刚过去的那样UINavigationBar.

任何帮助确定这条线的来源是值得赞赏的.

更新:在进一步的调查中,似乎只有在navigationItem.hidesSearchBarWhenScrolling设置为时才会发生false.如果它最初是隐藏的,那么前一个视图中的动画是平滑的,并且显示条形也是平滑的.

行的截屏示例

Luk*_*kas 5

测试您描述的导航项和搜索栏设置,我只能在过渡动画期间重现1px /点的线。

解决办法:该行实际上是背景布局视图forLastBaselineLayout),UINavigationBar由于存在错误的框架,最终可见UISearchBar。设置其背景以匹配您的导航栏颜色以将其隐藏在后站点

// MARK: UINavigationControllerDelegate

public func navigationController(_ navigationController: UINavigationController, willShow viewController: UIViewController, animated: Bool) {
    viewController.navigationController?.navigationBar
        .forLastBaselineLayout.backgroundColor = .red // TODO:
}
Run Code Online (Sandbox Code Playgroud)

确保将实现的对象UINavigationControllerDelegate设置为navigationController.delegate接收上述委托调用。

另外(不是问题的一部分): UISearchBar在控制器之间进行转换(推和弹出)时,似乎表现得很奇怪,尤其是当一个控制器具有/显示一个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
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 这对我不起作用...你知道为什么吗? (2认同)