奇怪的白色 space at UITableView header when using UISearchController with UITableViewController on iOS 10

Strange white space at UITableView header when using UISearchController with UITableViewController on iOS 10

白色space只出现在iOS10.

您将 UITableViewController 设置为 UISearchController 的 searchResultsController,但没有自动布局,也没有框架。

正如您在 UISearchController 的快速帮助中所读到的,如果您想在显示可搜索内容的同一视图控制器中显示搜索结果,则可以传递 nil。

所以如果你这样设置你的代码看起来没问题:

class ViewController: UIViewController {

let searchController = UISearchController(searchResultsController: nil)

override func viewDidLoad() {
        super.viewDidLoad()

        let tableView = UITableView(frame: view.bounds, style: .plain)
        tableView.dataSource = self

        view.addSubview(tableView)

        searchController.hidesNavigationBarDuringPresentation = false
        searchController.dimsBackgroundDuringPresentation = false
        navigationItem.titleView = searchController.searchBar
        searchController.searchBar.becomeFirstResponder()
        searchController.searchBar.text = "⬇️ What is this white space? ⬇️"
    }
}
...

最后,我找到了最简单的解决方案:

automaticallyAdjustsScrollViewInsets = false

我运行也遇到了这个问题。如果启用了垂直滚动指示器,您应该能够看到这是 UIScrollView 的插入问题。似乎只有当您使用 UITableViewcontroller 作为 UISearchControllersearchResultsController 时才会发生这种情况。

并且这个额外的 space 在视图的顶部和底部都可见。

这个答案不太好,但我现在添加这个。

if #available(iOS 10.0, *) {
    automaticallyAdjustsScrollViewInsets = false
    tableView.contentInset = UIEdgeInsetsMake(64, 0, 44, 0)
}

我尝试了一种似乎对我有用的不同方法。对于您应用的主要目标,将 "Hide Status Bar" 设置为 true。至少对我来说(Xcode 8 GM seed)这实际上并没有隐藏应用程序中的状态栏,但似乎已经纠正了间距问题。

虽然这解决了 phone 垂直方向时的问题,但它并没有完全解决水平方向时的间距问题。这段代码还解决了水平对齐屏幕上的问题:

    override var prefersStatusBarHidden: Bool {
        get {
            return UIApplication.shared.isStatusBarHidden
        }
    }

当然,将 prefersStatusBarHidden 值设置为 false 将完全禁用状态栏,但对于某些开发人员而言,这可能不是一个可行的解决方法。

希望这对您有所帮助。这有点乱,我希望 Apple 在未来的 iOS 更新中解决这个问题。

基于@yishus 的回答:

I ran into this problem as well. If you have the vertical scroll indicator enabled, you should be able to see that it's a UIScrollView's inset issue. And seems like it only happens when you use a UITableViewcontroller as the searchResultsController of a UISearchController.

And this extra space is visible at both the top and bottom of the view.

This answer is not pretty, but I'm adding this in for now.

if #available(iOS 10.0, *) {
    automaticallyAdjustsScrollViewInsets = false
    tableView.contentInset = UIEdgeInsetsMake(64, 0, 44, 0)
}

我禁用了垂直滚动指示器,但问题仍然存在。此外,您不能使用 #available 来检查 iOS 版本。它用于检查一个API在iOS版本中是否可用。所以我最终使用了这个解决方案:

搜索结果控制器(不是主视图控制器)中:

override func viewDidLoad() {
    super.viewDidLoad()

    if ProcessInfo().isOperatingSystemAtLeast(OperatingSystemVersion(majorVersion: 10,
                                                                     minorVersion: 0,
                                                                     patchVersion: 0)) {
        automaticallyAdjustsScrollViewInsets = false
    }
}

在主视图控制器中更新搜索结果时:

func updateSearchResults(for searchController: UISearchController) {
    if ProcessInfo().isOperatingSystemAtLeast(OperatingSystemVersion(majorVersion: 10,
                                                                     minorVersion: 0,
                                                                     patchVersion: 0)) {
        searchResultsController.tableView.contentInset = UIEdgeInsets(top: topLayoutGuide.length,
                                                                      left: 0,
                                                                      bottom: bottomLayoutGuide.length,
                                                                      right: 0)
    }

    // Filter results here
}

searchResultsController就是上面说的控制器

如果要处理方向,请在方向更改时再次设置 searchResultsController.tableView.contentInset

还有一个问题,每次出现主视图控制器(从另一个标签栏切换,弹出一个视图控制器,...),都会调用 updateSearchResults。由于我异步加载结果,这对性能非常不利。