在 UIViewAlertForUnsatisfiableConstraints 中使用 Autolayout 结果的可扩展 UITableView Cell [英] Expandable UITableView Cell using Autolayout results in UIViewAlertForUnsatisfiableConstraints

查看:32
本文介绍了在 UIViewAlertForUnsatisfiableConstraints 中使用 Autolayout 结果的可扩展 UITableView Cell的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用 UITableViewAutomaticDimension 行高和单元格自动布局的组合来制作可扩展单元格.为简单起见,我从以下简单的代码开始,我希望能正常工作:

I am trying to make expandable cells using combination of UITableViewAutomaticDimension row height and Autolayout of the cells. To make things simple, I started with the following simple code, that I expected to work:

import UIKit

class ViewController: UITableViewController {

    let cells = [Cell(), Cell(), Cell()]

    override func viewDidLoad() {
        super.viewDidLoad()
        tableView.rowHeight = UITableViewAutomaticDimension
        tableView.estimatedRowHeight = 50

        for cell in cells {
            cell.tableView = tableView
        }
    }

    override func numberOfSections(in tableView: UITableView) -> Int {
        return 1
    }

    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return 3
    }

    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        return cells[indexPath.row]
    }
}

class Cell: UITableViewCell {

    var cons: NSLayoutConstraint?
    var tableView: UITableView?

    init() {
        super.init(style: .default, reuseIdentifier: nil)

        let button = UIButton()
        contentView.addSubview(button)
        button.addTarget(self, action: #selector(Cell.tapped(_:)), for: .touchUpInside)
        button.setTitle("Press me", for: .normal)
        button.setTitleColor(.red, for: .normal)

        button.translatesAutoresizingMaskIntoConstraints = false

        // constraining the button to the view, so that buttons height would define cell height
        let constraints = [
            button.topAnchor.constraint(equalTo: contentView.topAnchor),
            button.rightAnchor.constraint(equalTo: contentView.rightAnchor),
            button.bottomAnchor.constraint(equalTo: contentView.bottomAnchor),
            button.leftAnchor.constraint(equalTo: contentView.leftAnchor),
        ]

        NSLayoutConstraint.activate(constraints)
        cons = button.heightAnchor.constraint(equalToConstant: 100)
        cons?.isActive = true
    }

    func tapped(_ sender: UIButton) {
        // change the height of the button, thus of the contentView too (since the button is constrained to the contentView)
        if cons?.constant == 100 {
            cons?.constant = 200
        } else {
            cons?.constant = 100
        }
        // tell the tableView to redraw itself to apply the change
        tableView?.beginUpdates()
        tableView?.setNeedsDisplay()
        tableView?.endUpdates()
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}

现在这似乎有效,但是,我仍然收到带有以下消息的 UIViewAlertForUnsatisfiableConstraints 警告:

Now this seems to be working, however, I still do get UIViewAlertForUnsatisfiableConstraints warning with the following message:

(
"<NSLayoutConstraint:0x17408c7b0 V:|-(0)-[UIButton:0x109e10290'Press me']   (active, names: '|':UITableViewCellContentView:0x109e0fd90 )>",
"<NSLayoutConstraint:0x17408c8a0 UIButton:0x109e10290'Press me'.bottom == UITableViewCellContentView:0x109e0fd90.bottom   (active)>",
"<NSLayoutConstraint:0x17408c990 UIButton:0x109e10290'Press me'.height == 200   (active)>",
"<NSLayoutConstraint:0x17408db10 'UIView-Encapsulated-Layout-Height' UITableViewCellContentView:0x109e0fd90.height == 100   (active)>"
)

 Will attempt to recover by breaking constraint 
 <NSLayoutConstraint:0x17408c990 UIButton:0x109e10290'Press me'.height == 200   (active)>

估计(或当前)行高似乎与我提供的自动布局约束相冲突.尽管如此,使用以下代码刷新 tableView 将按预期显示它:

It seems that the estimated (or current) row height collides with the autolayout constraint provided by me. Still, refreshing the tableView using following code will display it as expected:

tableView?.beginUpdates()
tableView?.setNeedsDisplay()
tableView?.endUpdates()

如何删除警告?

我知道简单地将高度约束的优先级更改为 999 将消除警告,但在我看来,将其删除是一种技巧,而不是解决方案.如果我错了,请解释.谢谢.

I am aware that simple changing the priority of the height constraint to 999 will remove the warning, but it seems to me as a hack to remove it, not as a solution. If I am mistaken, please explain. Thanks.

推荐答案

将高度约束优先级设置为 999 可能感觉像一个黑客,但根据 Apple 的文档:

Setting the height constraint priority to 999 may feel like a hack, but according to Apple's docs:

注意 不要觉得有义务使用所有 1000 个优先级值.事实上,优先级一般应围绕系统定义的低 (250)、中 (500)、高 (750) 和必需 (1000) 优先级聚集.您可能需要制定比这些值高或低一或两个点的约束,以帮助防止平局.如果您想超越这一点,您可能需要重新检查布局的逻辑.

NOTE Don’t feel obligated to use all 1000 priority values. In fact, priorities should general cluster around the system-defined low (250), medium (500), high (750), and required (1000) priorities. You may need to make constraints that are one or two points higher or lower than these values, to help prevent ties. If you’re going much beyond that, you probably want to reexamine your layout’s logic.

可能不太直观:

我想让按钮高度控制单元格高度,所以降低它的优先级????"

"I want the button height to control the cell height, so lower its priority????"

但是,这似乎是正确"的做法.

But, that does appear to be the "correct" way to do it.

参考:https://developer.apple.com/library/content/documentation/UserExperience/Conceptual/AutolayoutPG/AnatomyofaConstraint.html#//apple_ref/doc/uid/TP40010853-CH9-SW19

这篇关于在 UIViewAlertForUnsatisfiableConstraints 中使用 Autolayout 结果的可扩展 UITableView Cell的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆