选择时 UISearchBar 的宽度和位置会发生变化

UISearchBar width and position changes upon selection

我遇到了一个非常令人沮丧的问题,我确信有一个简单的解决方案,但对于我来说,我无法弄清楚。

我在 UIViewController 中有一个 UITableView。在工具栏上,我有一个可以 show/hide 搜索栏的按钮。一切都很好,除了令人讨厌的事实,即搜索栏在选择时向上移动 8 个像素(UITableView 和 SuperView 之间的原始边距)并扩展宽度以等于完整的超级视图。

我已经修复了函数 searchBarFrame() 的宽度问题,但是,它将 "Cancel" 按钮切成两半,所以它并不完美(见下文)。我真的很感激对这两个问题的任何想法。我已经根据我发现的其他解决方案尝试了 Extend Edges 和 Scroll View Insets 的所有组合,但没有任何效果。我真的不想将导航栏用作搜索栏,也不想完全转换为 UITableViewController。一定有办法让这项工作成功!

这是我的(相关的?)代码:

class ListVC: UIViewController UISearchControllerDelegate, UISearchBarDelegate, UISearchResultsUpdating {

@IBOutlet weak var tableView: UITableView!
@IBOutlet weak var searchBtn: UIBarButtonItem!

let searchController: UISearchController = UISearchController(searchResultsController: nil)

override func viewDidLoad() {
    super.viewDidLoad()

    tableView.dataSource = self
    tableView.delegate = self
}

func searchBarFrame() {
    var searchBarFrame = searchController.searchBar.frame
    searchBarFrame.size.width = tableView.frame.size.width
    searchController.searchBar.frame = searchBarFrame
}

func showSearchController() {
    searchController.isActive = true
    searchBarFrame()

    searchController.searchResultsUpdater = self
    searchController.searchBar.delegate = self

    searchController.dimsBackgroundDuringPresentation = false
    searchController.hidesNavigationBarDuringPresentation = false
    definesPresentationContext = true

    searchController.searchBar.placeholder = "Search Places"
    searchController.searchBar.roundCorners(corners: [.topLeft, .topRight, .bottomLeft, .bottomRight], radius: 5.0)
    searchController.searchBar.barTintColor = UIColor.blurColor

    tableView.tableHeaderView = searchController.searchBar
}

func hideSearchController() {
    tableView.tableHeaderView = nil
    searchController.isActive = false
}

@IBAction func onSearchBtnPress(sender: UIBarButtonItem) {
    if !searchController.isActive {
        showSearchController()
    } else {
        hideSearchController()
    }
}

我认为使用 NSLayoutConstraint 来定位和调整视图大小可以解决这个问题。

例如:

private let margin: CGFloat = 15.0

tableView.translatesAutoresizingMaskIntoConstraints = false
searchBar.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
    tableView.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor, constant: margin),
    tableView.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor, constant: margin),
    tableView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor),
    tableView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor),
    searchBar.widthAnchor.constraint(equalTo: tableView.widthAnchor)
])

跟进,以防其他人遇到此问题。经过大量的时间和努力,我的原始设置始终无法正常工作。相反,我从头开始并以不同的方式接近它。

在情节提要中(您也可以通过编程方式执行此操作,但我选择了更简单的方法,因为我受够了),我将 UISearchBar 放在 UIStackView 中的 UIView 中。我将 Stackview 的前导和尾随约束设置为 uitableview,底部到 uitableview 的顶部,顶部到顶部布局视图的底部。 UIView 的唯一限制是 56 的高度(典型的搜索栏高度)和 999 的优先级(如果你想显示和隐藏)。

这解决了所有问题,代码也非常简单。

class MyVC: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        searchBar.delegate = self
        searchView.isHidden = true
    }

    @IBAction func onSearchBtnPress(sender: UIBarButtonItem) {
        if searchView.isHidden {
            searchView.isHidden = false
        } else {
            searchView.isHidden = true
        }
    }
}

extension MyVC: UISearchBarDelegate {

    func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
        // do something
}