ios - Swift 中 NSLayoutConstraints 的奇怪行为

标签 ios swift uitableview nslayoutconstraint

我的 View 顶部有一个 textField,还有一个应该放在 textField 下方的 tableView。

所以我添加它们的代码如下所示:

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并将其高度设置为tableView的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

当我完成滚动时,它会停在 View 中间 enter image description here

有没有办法解决这个问题?有什么问题可以问我

最佳答案

让我们设置 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 淡入/淡出 tableView:

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)
}

关于ios - Swift 中 NSLayoutConstraints 的奇怪行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52518750/

相关文章:

ios - 当用户向左滑动时在 UIWebView 上加载另一个页面

ios - 在不同的类swift中以编程方式创建一个按钮

ios - 获取 iPhone 所在的国家(没有 CLLocationManager)

Swift 的三元条件运算符从两个非可选值返回可选值?

iOS TableView 行删除

ios - UIButton 移动到自定义单元格中的 Storyboard

ios - 子类化 PFUser

json - 在 NSHomeDirectory 中写入 NSData

ios - 没有动画的deleteRowsAtIndexPaths

ios - 使用 CATransform3DMakeRotation 时的 uiview zorder