Я хочу, чтобы ячейки UITableView
адаптировались к размеру их содержимого в iOS 10 и 11 с помощью:
tableView.estimatedRowHeight = UITableViewAutomaticDimension // default in iOS 11
tableView.rowHeight = UITableViewAutomaticDimension
Без установки tableView.rowHeight
на явное числовое значение, которое является новым значением по умолчанию в iOS 11.
UIView
не имеет внутреннего размера содержимого, поэтому я установил ограничение макета для его привязки по высоте. Однако этот якорь ломается во время выполнения.
Какие внутренние ограничения в UITableViewCell
необходимы, чтобы ячейка могла адаптироваться к своему содержимому?
Это работает только в iOS 11:
class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
override func viewDidLoad() {
super.viewDidLoad()
let tableView = UITableView()
tableView.register(UITableViewCell.self, forCellReuseIdentifier: "cell")
tableView.estimatedRowHeight = UITableViewAutomaticDimension
tableView.rowHeight = UITableViewAutomaticDimension
tableView.delegate = self
tableView.dataSource = self
tableView.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(tableView)
NSLayoutConstraint.activate([
tableView.topAnchor.constraint(equalTo: view.topAnchor),
tableView.bottomAnchor.constraint(equalTo: view.bottomAnchor),
tableView.leftAnchor.constraint(equalTo: view.leftAnchor),
tableView.rightAnchor.constraint(equalTo: view.rightAnchor)
])
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = UITableViewCell(style: UITableViewCellStyle.subtitle, reuseIdentifier: "cell")
let view = UIView()
view.backgroundColor = .blue
view.translatesAutoresizingMaskIntoConstraints = false
cell.contentView.addSubview(view)
NSLayoutConstraint.activate([
view.topAnchor.constraint(equalTo: cell.contentView.topAnchor),
view.bottomAnchor.constraint(equalTo: cell.contentView.bottomAnchor),
view.leftAnchor.constraint(equalTo: cell.contentView.leftAnchor),
view.rightAnchor.constraint(equalTo: cell.contentView.rightAnchor),
view.heightAnchor.constraint(equalToConstant: 300)
])
return cell
}
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 1
}
}
В iOS 10 возникает эта ошибка времени выполнения, и размер ячейки не адаптируется:
[LayoutConstraints] Невозможно одновременно удовлетворить ограничения. Вероятно, по крайней мере, одно из ограничений в следующем списке вам не нужно. Попробуйте следующее: (1) посмотрите на каждое ограничение и попытайтесь выяснить, чего вы не ожидаете; (2) найдите код, который добавил нежелательное ограничение или ограничения, и исправьте его. ("NSLayoutConstraint: 0x17009c020 V: | - (0) - [test.MyView: 0x11dd1acb0] (активно, имена: '|': UITableViewCellContentView: 0x11dd15220)», «NSLayoutConstraint: 0x17009c160 = MydView: 0x11dd15220.bottom (активный) "," NSLayoutConstraint: 0x17009c390 test.MyView: 0x11dd1acb0.height == 300 (активный) "," NSLayoutConstraint: 0x17009be40 'UIView-Encapsulated-Layout-Height' UITableView2: ) ")
Попытается восстановить, нарушив ограничение NSLayoutConstraint: 0x17009c390 test.MyView: 0x11dd1acb0.height == 300 (активно)
Сделайте символическую точку останова в UIViewAlertForUnsatisfiableConstraints, чтобы отловить это в отладчике. Также могут быть полезны методы из категории UIConstraintBasedLayoutDebugging в UIView, перечисленные в UIKit / UIView.h.
Это работает в iOS 10 и 11, но не использует новый подход iOS 11, поскольку tableView.estimatedRowHeight
не UITableViewAutomaticDimension
:
class ViewController_TableView: UIViewController, UITableViewDataSource, UITableViewDelegate {
override func viewDidLoad() {
super.viewDidLoad()
let tableView = UITableView()
tableView.register(UITableViewCell.self, forCellReuseIdentifier: "cell")
tableView.estimatedRowHeight = 30
tableView.rowHeight = UITableViewAutomaticDimension
tableView.delegate = self
tableView.dataSource = self
tableView.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(tableView)
NSLayoutConstraint.activate([
tableView.topAnchor.constraint(equalTo: view.topAnchor),
tableView.bottomAnchor.constraint(equalTo: view.bottomAnchor),
tableView.leftAnchor.constraint(equalTo: view.leftAnchor),
tableView.rightAnchor.constraint(equalTo: view.rightAnchor)
])
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = UITableViewCell(style: UITableViewCellStyle.subtitle, reuseIdentifier: "cell")
let view = MyView()
view.backgroundColor = .blue
view.translatesAutoresizingMaskIntoConstraints = false
cell.contentView.addSubview(view)
NSLayoutConstraint.activate([
view.topAnchor.constraint(equalTo: cell.contentView.topAnchor),
view.bottomAnchor.constraint(equalTo: cell.contentView.bottomAnchor),
view.leftAnchor.constraint(equalTo: cell.contentView.leftAnchor),
view.rightAnchor.constraint(equalTo: cell.contentView.rightAnchor)
])
return cell
}
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 1
}
}
class MyView: UIView {
override var intrinsicContentSize: CGSize {
get {
return CGSize(width: 300, height: 300)
}
}
}
rowHeight
не установлено вUITableViewAutomaticDimension
, что не так, как предполагается в iOS 11. Ваша ссылка - это пример до iOS 11. - person Manuel   schedule 03.10.2017999.9
, что немедленно решит проблему прерывания работы; но на самом деле это не объяснение того, почему ограничение нарушается в первую очередь ... (это может быть связано с представлением или округлением плавающих значений, но это мое безумное предположение) , однако ваш пример также является довольно гипотетическим, поскольку никто на самом деле не создает пользовательский интерфейс, подобный этому, на практике, поэтому, вероятно, никому на самом деле не нужно сталкиваться с такой проблемой, как когда-либо. - person holex   schedule 03.10.2017xib
, предопределенные ограничения загружаются уже правильно во время инициализации, но когда вы создали ячейку программно, после инициализации в ячейке вообще нет ограничений завершено, поэтому iOS добавляет ограничения по умолчанию в ячейку, и они, похоже, мешают ограничениям, которые вы пытаетесь добавить после, и это может быть прямым ответом на ваши проблемы: почему пользовательский интерфейс не должен создавать так, потому что в вашем собственном примере ремонтопригодность намного хуже. - person holex   schedule 03.10.2017