UITableView 当更改影响出队后单元格高度的约束时,最终会导致约束损坏

2024-02-12

此代码块试图触及问题的核心。如果在使单元出队后(通过configure),约束发生变化,单元格高度也发生变化,然后您最终会收到破坏约束的警告(Unable to simultaneously satisfy constraints...)。但是,它显示正确。

import UIKit
class ViewController: UIViewController {

    @IBOutlet var tableView: UITableView!

    override func viewDidLoad() {
        super.viewDidLoad()
        tableView.delegate = self
        tableView.dataSource = self
        tableView.registerClass(Cell.self, forCellReuseIdentifier: "cell")
        tableView.estimatedRowHeight = 55.0
        tableView.rowHeight = UITableViewAutomaticDimension
    }

}

extension ViewController: UITableViewDelegate, UITableViewDataSource {
    func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return array.count
    }

    func numberOfSectionsInTableView(tableView: UITableView) -> Int {
        return 1
    }

    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCellWithIdentifier("cell") as! Cell
        cell.configure(array[indexPath.row])
        return cell
    }

    func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) {
    }
}

enum Position {
    case Top
    case Middle
    case Bottom
}

class Cell: UITableViewCell {

    private var topConstraint: NSLayoutConstraint!
    private var bottomConstraint: NSLayoutConstraint!

    private let label = UILabel()
    private var previous: Position?

    override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
        super.init(style: style, reuseIdentifier: reuseIdentifier)

        label.backgroundColor = UIColor.redColor().colorWithAlphaComponent(0.5)
        label.textColor = UIColor.blackColor()
        label.translatesAutoresizingMaskIntoConstraints = false
        contentView.addSubview(label)
        label.leadingAnchor.constraintEqualToAnchor(contentView.leadingAnchor, constant: 30).active = true
        label.trailingAnchor.constraintEqualToAnchor(contentView.trailingAnchor, constant: -30).active = true
        topConstraint = label.topAnchor.constraintEqualToAnchor(contentView.topAnchor)
        topConstraint.active = true
        bottomConstraint = label.bottomAnchor.constraintEqualToAnchor(contentView.bottomAnchor)
        bottomConstraint.active = true
    }

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

    func configure(position: Position) {
        if previous != nil {print("previous \(previous!) new \(position)")}
        topConstraint.constant = position == .Top ? 30 : 0
        bottomConstraint.constant = position == .Bottom ? -30 : 0
        label.text = String(position)
        previous = position
    }
}

let array: [Position] = [.Top, .Middle, .Middle, .Middle, .Bottom,
                         .Top, .Middle, .Middle, .Middle, .Middle, .Bottom,
                         .Top, .Middle, .Middle, .Bottom,
                         .Top, .Middle, .Middle, .Middle,  .Middle, .Middle, .Middle, .Bottom,
                         .Top, .Middle, .Middle, .Middle, .Bottom,
                         .Top, .Bottom,
                         .Top, .Middle, .Middle, .Middle,  .Middle, .Middle, .Middle, .Bottom,
                         .Top, .Middle, .Middle, .Middle, .Bottom,
                         .Top, .Middle, .Middle, .Bottom,
                         .Top, .Middle, .Middle, .Middle,  .Middle, .Middle, .Middle, .Bottom,
]

错误信息是...

2016-04-28 22:56:29.831 test-constraint-change[51059:3776208] Unable to simultaneously satisfy constraints.
Probably at least one of the constraints in the following list is one you don't want. 
Try this: 
    (1) look at each constraint and try to figure out which you don't expect; 
    (2) find the code that added the unwanted constraint or constraints and fix it. 
(
"<NSLayoutConstraint:0x7c117c70 V:|-(30)-[UILabel:0x7c148770'Middle']   (Names: '|':UITableViewCellContentView:0x7c149b70 )>",
"<NSLayoutConstraint:0x7c115bd0 UILabel:0x7c148770'Middle'.bottom == UITableViewCellContentView:0x7c149b70.bottom>",
"<NSLayoutConstraint:0x7c14a3f0 'UIView-Encapsulated-Layout-Height' V:[UITableViewCellContentView:0x7c149b70(20.5)]>"
)

Will attempt to recover by breaking constraint <NSLayoutConstraint:0x7c115bd0 UILabel:0x7c148770'Middle'.bottom == UITableViewCellContentView:0x7c149b70.bottom>

Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints to catch this in the debugger.
The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKit/UIView.h> may also be helpful.

将约束的优先级设置为 999。就像现在一样,它将正确显示。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

UITableView 当更改影响出队后单元格高度的约束时,最终会导致约束损坏 的相关文章

随机推荐