Странное поведение NSLayoutConstraints в Swift - PullRequest
0 голосов
/ 26 сентября 2018

У меня есть textField сверху моего представления и tableView, который должен быть помещен ниже textField.

Так что мой код для их добавления выглядит следующим образом:

private func setupSearchBar() {
    searchtextField = UITextField()
    mapView.addSubview(searchtextField)
    searchtextField.translatesAutoresizingMaskIntoConstraints = false

    let constraints = [
        NSLayoutConstraint(item: searchtextField, attribute: .leading, relatedBy: .equal, toItem: mapView.safeAreaLayoutGuide, attribute: .leading, multiplier: 1.0, constant: 16.0),
        NSLayoutConstraint(item: searchtextField, attribute: .trailing, relatedBy: .equal, toItem: mapView.safeAreaLayoutGuide, attribute: .trailing, multiplier: 1.0, constant: -16.0),
        NSLayoutConstraint(item: searchtextField, attribute: .top, relatedBy: .equal, toItem: mapView.safeAreaLayoutGuide, attribute: .top, multiplier: 1.0, constant: 24.0),
        NSLayoutConstraint(item: searchtextField, attribute: .height, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 1.0, constant: 46.0)
        ]

    NSLayoutConstraint.activate(constraints)
}

после этогоЯ настраиваю свой tableView:

private func setupResultsTableView() {
    tableView = UITableView()
    mapView.addSubview(tableView)
    tableView.translatesAutoresizingMaskIntoConstraints = false

    tableViewHeightAnchor = tableView.heightAnchor.constraint(equalToConstant: 0)
    let constraints = [
        tableView.safeAreaLayoutGuide.topAnchor.constraint(equalTo: searchtextField.safeAreaLayoutGuide.bottomAnchor),
        tableView.safeAreaLayoutGuide.leadingAnchor.constraint(equalTo: mapView.safeAreaLayoutGuide.leadingAnchor),
        tableView.safeAreaLayoutGuide.trailingAnchor.constraint(equalTo: mapView.trailingAnchor),
        tableViewHeightAnchor!,
        tableView.safeAreaLayoutGuide.bottomAnchor.constraint(lessThanOrEqualToSystemSpacingBelow: view.safeAreaLayoutGuide.bottomAnchor, multiplier: 1.0)
    ]
    NSLayoutConstraint.activate(constraints)
}

Что я хочу сделать, это: 1. Установить для tableView высоту 0 2. Когда пользователь начинает вводить мое textField, в соответствии с результатами поискаотобразить tablView и установить его высоту равным contentSize таблицы.Таким образом, максимальный размер будет привязан к нижней части устройства, и если отображаются 1-2 результата, то для уменьшения размера tableView.

Когда пользователь начинает печатать, я запускаю следующее:

func textFieldDidBeginEditing(_ textField: UITextField) {        
    filterContentForSearchText(textField.text!)
    tableView.reloadData()

    UIView.animate(withDuration: 0.6) {
        self.tableView.layoutIfNeeded()

        if textField.isEditing {
            self.tableViewHeightAnchor.constant = self.tableView.contentSize.height
        } else {
            self.tableViewHeightAnchor.constant = 0.0
        }
    }
}

Но что-то не так в моем коде, потому что я получаю такие уродливые результаты: когда я начинаю смахивать, tableView начинает подниматься и перебирает мое textField

enter image description here

и когда я заканчиваю прокрутку, она останавливается в середине вида enter image description here

Есть ли способ исправить эту проблему?Если у вас есть какие-либо вопросы, пожалуйста, спросите меня

1 Ответ

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

Позволяет установить полную высоту tableView и переключать его видимость следующим образом:

tableView.backgroundColor = .clear
tableView.isHidden = true
tableView.tableFooterView = UIView()

С этими ограничениями для tableView:

NSLayoutConstraint.activate([
    tableView.topAnchor.constraint(equalTo: searchtextField.bottomAnchor),
    tableView.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor),
    tableView.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor),
    tableView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor, multiplier: 1.0)
])

Теперь мы можем использовать UITextFieldDelegate методы для переключениянаше tableView:

func textFieldDidBeginEditing(_ textField: UITextField) {
    self.toggleSearch(true)
}

func textFieldShouldReturn(_ textField: UITextField) -> Bool {
    textField.resignFirstResponder()
    return true
}

func textFieldDidEndEditing(_ textField: UITextField) {
    self.toggleSearch(false)
}

private func toggleSearch(_ value: Bool) {
    self.tableView.isHidden = !value
}

Не забудьте установить searchtextField.delegate = self

Дополнительно , вы можете добавить полупрозрачный backgroundView и использовать эту анимированную версию toggleSearch постепенное увеличение / уменьшение табличного изображения:

let backgroundView = UIView()
backgroundView.backgroundColor = UIColor.black.withAlphaComponent(0.3)
backgroundView.layer.opacity = 0
tableView.backgroundView = backgroundView

private func toggleSearch(_ value: Bool) {
    var completionBlock: ((Bool) -> Void)?
    if (value) {
        self.tableView.isHidden = false
    } else {
        completionBlock = { [weak self] _ in self?.tableView.isHidden = true }
    }

    UIView.animate(withDuration: 0.3, animations: {
        self.tableView.backgroundView?.layer.opacity = value ? 1 : 0
    }, completion: completionBlock)
}
...