У меня есть сворачиваемый заголовок для разделов uitableview, основанный на другом сообщении о переполнении стека (не знаю, где сейчас, как это было несколько месяцев назад). Так получилось, что тестеры обнаружили странную ошибку, при которой свертывание всех разделов сводит представление заголовка таблицы вниз.
* редактировать заголовок табличного представления - это просто представление пользовательского интерфейса, которое я поместил в раскадровку внутри табличного представления над ячейкой прототипа. Нет существенных ограничений. Просто высота для ячеек и заголовка. Вид таблицы прикреплен к безопасной зоне.
Все выглядит нормально, пока вы не развернете один из разделов за пределами экрана, затем прокрутите его вверх, чтобы строки начали скользить под плавающим заголовком раздела в верхней части. Затем вы нажимаете, чтобы свернуть его. Он сворачивается, но представление заголовка сносится. Похоже, это происходит, когда разделы помещаются на одном экране, а строки немного прокручивались до свертывания.
Любая помощь будет оценена.
В моем демонстрационном проекте (рад поделиться), когда четыре раздела свернуты, это выглядит так:
Когда пользователь раскрывает некоторые разделы, прокручивает заголовок раздела вверху, а содержимое прокручивается под ним, а затем сворачивает закрепленный заголовок раздела, это может выглядеть так:
У меня есть протокол для делегата:
protocol CollapsibleHeaderViewDelegate: class {
func toggleSection(header: CollapsibleSectionHeader, section: Int)
}
protocol SectionHeaderCollapsible {
var isCollapsed: Bool { get }
var rowCount: Int { get }
}
И подкласс UITableVieHeaderFooterView:
class CollapsibleHeader: UITableViewHeaderFooterView {
@IBOutlet var sectionHeaderLabel: UILabel!
var collapsed = false
weak var delegate: CollapsibleHeaderViewDelegate?
var sectionItem: SectionHeaderCollapsible?
static let reuseIdentifer = "CollapsibleHeader"
func configure(headerText: String) {
textLabel?.text = headerText
}
override func awakeFromNib() {
super.awakeFromNib()
addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(didTapHeader)))
}
@objc private func didTapHeader(gestureRecognizer: UITapGestureRecognizer) {
guard let header = gestureRecognizer.view as? CollapsibleHeader else { return }
delegate?.toggleSection(header: self, section: header.tag)
}
}
Тогда делегат делает что-то вроде. это:
struct CollapsibleSection: SectionHeaderCollapsible {
var isCollapsed: Bool = false
var rowCount: Int {
get {
return isCollapsed ? 0 : dataContents.count
}
}
var dataContents: [String]
}
class ViewController: UIViewController {
@IBOutlet var tableView: UITableView!
@IBOutlet var headerView: UITableView!
var sections = [CollapsibleSection(isCollapsed: false, dataContents: ["first", "second"]),
CollapsibleSection(isCollapsed: false, dataContents: ["red", "blue"]),
CollapsibleSection(isCollapsed: false, dataContents: ["seven", "five"]),
CollapsibleSection(isCollapsed: false, dataContents: ["Josephine", "Edward"])]
override func viewDidLoad() {
super.viewDidLoad()
tableView.dataSource = self
tableView.delegate = self
let nib = UINib(nibName: "CollapsibleHeader", bundle: nil)
tableView.register(nib, forHeaderFooterViewReuseIdentifier: "CollapsibleHeader")
}
}
extension ViewController: UITableViewDataSource, UITableViewDelegate {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return sections[section].rowCount
}
func numberOfSections(in tableView: UITableView) -> Int {
return sections.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
guard let cell = tableView.dequeueReusableCell(withIdentifier: "Cell") else { fatalError() }
cell.textLabel?.text = sections[indexPath.section].dataContents[indexPath.row]
return cell
}
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
guard let header = self.tableView.dequeueReusableHeaderFooterView(withIdentifier: "CollapsibleHeader") as? CollapsibleHeader else { fatalError() }
header.sectionHeaderLabel.text = "Section \(section + 1)"
header.delegate = self
header.tag = section
return header
}
func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return 100
}
}
extension ViewController: CollapsibleHeaderViewDelegate {
func toggleSection(header: CollapsibleHeader, section: Int) {
sections[section].isCollapsed = !sections[section].isCollapsed
tableView.reloadSections([section], with: .fade)
}
}
EDIT:
Похоже, мои коллеги создали работу, основанную на (или, по крайней мере, похожем) на ваш ответ:
if tableView.contentOffset.y < 0 {
var offset = tableView.contentOffset
offset.y = tableView.contentSize.height - tableView.bounds.height
tableView.setContentOffset(offset, animated: true)
} else {
tableView.setContentOffset(tableView.contentOffset, animated: true)
}