Я пытаюсь создать табличное представление, чьи ячейки расширяются при выделении ячейки и остаются развернутыми, пока не будут выбраны снова.
Я пытаюсь определить высоту ячеек, определяемую их содержанием. Я уже знаю, как установить rowHeight иViewgedRowHeight для TableView, чтобы получить возможность самостоятельно измерять размеры, так что это не проблема.
ViewController.swift:
import UIKit
class ViewController: UIViewController {
lazy var tableView: UITableView = {
let tv = UITableView(frame: .zero, style: .plain)
tv.register(ExpandingCell.self, forCellReuseIdentifier: ExpandingCell.reuseIdentifier)
tv.estimatedRowHeight = 85.0
tv.rowHeight = UITableViewAutomaticDimension
return tv
}()
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
self.view.addSubview(tableView)
tableView.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
tableView.topAnchor.constraint(equalTo: self.view.topAnchor),
tableView.bottomAnchor.constraint(equalTo: self.view.bottomAnchor),
tableView.leadingAnchor.constraint(equalTo: self.view.leadingAnchor),
tableView.trailingAnchor.constraint(equalTo: self.view.trailingAnchor)])
tableView.dataSource = self
tableView.delegate = self
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
extension ViewController: UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 50
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: ExpandingCell.reuseIdentifier, for: indexPath) as! ExpandingCell
return cell
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return UITableViewAutomaticDimension
}
func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
return 50.0
}
}
extension ViewController: UITableViewDelegate {
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
}
func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) {
}
}
ExpandingCell.swift
import UIKit
class ExpandingCell: UITableViewCell {
static let reuseIdentifier = "dafasdfadfagr"
let minimumDisplayedView = UIView()
let extraContentView = UIView()
var expandingConstraint: NSLayoutConstraint?
override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
commonInit()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
commonInit()
}
private func commonInit() {
self.setupViews()
self.contentView.clipsToBounds = true
}
private func setupViews() {
self.addSubviews()
self.customizeSubviews()
self.constrainSubviews()
}
private func addSubviews() {
self.contentView.addSubview(minimumDisplayedView)
self.contentView.addSubview(extraContentView)
}
private func customizeSubviews() {
self.customizeMinimumDisplayedView()
self.customizeExtraContentView()
}
private func constrainSubviews() {
self.constrainMinimumDisplayedView()
self.constrainExtraContentView()
}
// MARK: - MinimumDisplayView
private func customizeMinimumDisplayedView() {
minimumDisplayedView.backgroundColor = .blue
}
private func constrainMinimumDisplayedView() {
minimumDisplayedView.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
minimumDisplayedView.heightAnchor.constraint(equalToConstant: 50),
minimumDisplayedView.topAnchor.constraint(equalTo: self.contentView.topAnchor),
minimumDisplayedView.leadingAnchor.constraint(equalTo: self.contentView.leadingAnchor),
minimumDisplayedView.trailingAnchor.constraint(equalTo: self.contentView.trailingAnchor)
])
expandingConstraint = minimumDisplayedView.bottomAnchor.constraint(equalTo: self.contentView.bottomAnchor)
expandingConstraint?.isActive = true
}
// MARK: - ExtraContentView
private func customizeExtraContentView() {
extraContentView.backgroundColor = .red
}
private func constrainExtraContentView() {
extraContentView.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
extraContentView.heightAnchor.constraint(equalToConstant: 200),
extraContentView.topAnchor.constraint(equalTo: minimumDisplayedView.bottomAnchor),
extraContentView.leadingAnchor.constraint(equalTo: self.contentView.leadingAnchor),
extraContentView.trailingAnchor.constraint(equalTo: self.contentView.trailingAnchor)
])
}
// MARK: - Animate Expansion
// override func setSelected(_ selected: Bool, animated: Bool) {
// super.setSelected(selected, animated: animated)
// print("selected: \(selected)")
// resize(selected)
// }
private func resize(_ expand: Bool) {
expandingConstraint?.isActive = false
if expand {
expandingConstraint = extraContentView.bottomAnchor.constraint(equalTo: self.contentView.bottomAnchor)
expandingConstraint?.isActive = true
} else {
expandingConstraint = minimumDisplayedView.bottomAnchor.constraint(equalTo: self.contentView.bottomAnchor)
expandingConstraint?.isActive = true
}
UIView.animate(withDuration: 0.3) {
self.layoutIfNeeded()
}
}
}
У меня есть 2 вида, которые добавляются в contentView и прикрепляют края contentView только к первому виду при инициализации ячейки. Первый вид синий и короткий, а второй красный и высокий.
Я бы ожидал, что tableView изначально будет выглядеть синим, но вместо этого он выглядит так:
Я подозреваю, что это как-то связано с расположением ячеек в жизненном цикле представления, поэтому я также натолкнулся на следующий ответ: перезагрузить просмотр таблицы после первой загрузки в качестве временного решения
Когда я запускаю код, я получаю эти ошибки ограничения
2018-05-05 18:00:15.108634-0400 TestExpandingCells[1022:13932317] [LayoutConstraints] 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:0x6000000961c0 UIView:0x7fe583700df0.height == 50 (active)>",
"<NSLayoutConstraint:0x600000096580 V:|-(0)-[UIView:0x7fe583700df0] (active, names: '|':UITableViewCellContentView:0x7fe583704850 )>",
"<NSLayoutConstraint:0x600000096760 UIView:0x7fe583700df0.bottom == UITableViewCellContentView:0x7fe583704850.bottom (active)>",
"<NSLayoutConstraint:0x600000096bc0 'UIView-Encapsulated-Layout-Height' UITableViewCellContentView:0x7fe583704850.height == 50 (active)>"
)
Последнее ограничение в этом списке, 'UIView-Encapsulated-Layout-Height', похоже, происходит от некоторой вещи autoresizingmask-to-constraint, которую UIKit создает для размещения ячейки.
Итак, мой вопрос: как я могу удалить это ограничение, чтобы AutoLayout полностью справлялся с созданием моих ячеек, без обходного пути.
Я также предпочел бы, чтобы все это содержалось в классе ExpansionCell, а не в методах делегатов tableview.
Бонусные баллы, если вы также найдете способ вызвать расширение ячейки с помощью AutoLayout.