#ios #swift #uitableview #uistackview
#iOS #swift #uitableview #uistackview
Вопрос:
Я пытаюсь создать UITableView
скрытое вложенное представление внизу, которое будет открываться при нажатии на ячейку. У меня есть следующий демонстрационный код:
class ViewController: UIViewController {
let tableView = UITableView()
override func viewDidLoad() {
super.viewDidLoad()
view.addSubview(tableView)
tableView.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
tableView.bottomAnchor.constraint(equalTo: view.bottomAnchor),
tableView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
tableView.topAnchor.constraint(equalTo: view.topAnchor),
tableView.trailingAnchor.constraint(equalTo: view.trailingAnchor)
])
tableView.separatorStyle = .none
tableView.register(ExpandTableCell.self, forCellReuseIdentifier: "Cell")
tableView.dataSource = self
tableView.delegate = self
}
}
extension ViewController: UITableViewDataSource {
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell")
return cell ?? UITableViewCell()
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 3
}
}
extension ViewController: UITableViewDelegate {
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
guard let cell = tableView.cellForRow(at: indexPath) as? ExpandTableCell else { return }
tableView.performBatchUpdates({ cell.animate() }, completion: nil)
}
}
И ячейка:
class ExpandTableCell: UITableViewCell {
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
setup()
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
private func setup() {
setupViews()
}
private let blueView = UIView()
// MARK: - Views
private func setupViews() {
selectionStyle = . none
let titleLabel = UILabel()
titleLabel.text = "Some Title"
let subtitleLabel = UILabel()
subtitleLabel.text = "Some othere sdfhdslkjl dsfljdslfj sdlj sdfldsjfldsjf sdfjdslfjds"
subtitleLabel.numberOfLines = 2
blueView.backgroundColor = .blue
blueView.translatesAutoresizingMaskIntoConstraints = false
blueView.heightAnchor.constraint(equalToConstant: 50.0).isActive = true
let stackView = UIStackView(arrangedSubviews: [titleLabel, subtitleLabel, blueView])
stackView.axis = .vertical
stackView.spacing = 8.0
blueView.isHidden = true
addSubview(stackView)
stackView.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
stackView.topAnchor.constraint(equalTo: topAnchor),
stackView.leadingAnchor.constraint(equalTo: leadingAnchor),
stackView.trailingAnchor.constraint(equalTo: trailingAnchor),
stackView.bottomAnchor.constraint(equalTo: bottomAnchor)
])
}
func animate() {
UIView.animate(withDuration: 0.1, animations: { [blueView] in
blueView.isHidden.toggle()
})
}
}
Проблема в том, что анимация имеет следующий эффект:
Он сжимает содержимое метки над ним. Он должен просто скользить вниз снизу.
Что я здесь делаю не так?
Комментарии:
1. Попробуйте изменить продолжительность анимации на
0.3
… в качестве примечания, убедитесь, что вы добавляете и ограничиваете вложенные представления в ячейкуcontentView
, а не в саму ячейку.
Ответ №1:
Просто измените время анимации, чтобы оно соответствовало времени просмотра таблицы. Попробуйте 0.3
func animate() {
UIView.animate(withDuration: 0.3, animations: { [blueView] in
blueView.isHidden.toggle()
})
}
Артефакт исчез.
Комментарии:
1. Еще одна деталь: вы должны добавить свой вид стека в ячейку
contentView
, а не в саму ячейку. В противном случае вы можете столкнуться с проблемами позже.