Расширяемая ячейка UITableView с использованием результатов Autolayout в UIViewAlertForUnsatisfiableConstraints
Я пытаюсь сделать расширяемые клетки, используя комбинацию UITableViewAutomaticDimension
высота строки и автопрокладка ячеек. Чтобы упростить задачу, я начал со следующего простого кода, который, как я ожидал, будет работать:
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
предупреждение со следующим сообщением:
(
"<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 с использованием следующего кода отобразит его, как и ожидалось:
tableView?.beginUpdates()
tableView?.setNeedsDisplay()
tableView?.endUpdates()
Как убрать предупреждение?
Я знаю, что простое изменение приоритета ограничения по высоте на 999 удалит предупреждение, но мне кажется, что его нужно удалить, а не решение. Если я ошибаюсь, пожалуйста, объясните. Благодарю.
2 ответа
Установка приоритета ограничения высоты на 999 может показаться хаком, но в соответствии с документами Apple:
ПРИМЕЧАНИЕ. Не считайте себя обязанным использовать все 1000 значений приоритета. На самом деле, приоритеты должны в целом объединяться в систему с низкими (250), средними (500), высокими (750) и обязательными (1000) приоритетами, определенными системой. Вам может потребоваться установить ограничения, которые на одну или две точки выше или ниже этих значений, чтобы помочь предотвратить связи. Если вы идете намного дальше, вы, вероятно, захотите пересмотреть логику вашего макета.
Вероятно, немного меньше, чем интуитивно
"Я хочу, чтобы высота кнопки контролировала высоту ячейки, поэтому снизьте ее приоритет????"
Но, похоже, это "правильный" способ сделать это.
Удалите ограничение по высоте, т.е. 200, так как оно противоречит верхнему и нижнему ограничениям.
Надеюсь, поможет..