Как оживить представление заголовка UITableView
Мне нужно анимировать вставку вида заголовка tableview. Я хочу, чтобы строки таблицы скользили вниз, в то время как представление заголовка расширяет рамки.
Пока что лучший результат, полученный с помощью следующего кода:
[self.tableView beginUpdates];
[self.tableView setTableHeaderView:self.someHeaderView];
[self.tableView endUpdates];
Проблема с этим решением заключается в том, что сам заголовок не анимируется, его кадр не расширяется.
Таким образом, эффект, который я получаю, заключается в том, что строки таблицы скользят вниз (как я хочу), но сразу отображается представление заголовка, и я хочу, чтобы он расширил его фрейм с анимацией.
Любые идеи?
Спасибо.
Ответы
Ответ 1
имеют рамку заголовка в CGRectZero
и установите его фрейм с помощью анимации
[self.tableView beginUpdates];
[self.tableView setTableHeaderView:self.someHeaderView];
[UIView animateWithDuration:.5f animations:^{
CGRect theFrame = someBigger.frame;
someHeaderView.frame = theFrame;
}];
[self.tableView endUpdates];
Ответ 2
Вот что я получил для работы в Swift с начальной высотой кадра, равной нулю, и обновив ее до полной высоты при закрытии анимации:
// Calculate new frame size for the table header
var newFrame = tableView.tableHeaderView!.frame
newFrame.size.height = 42
// Get the reference to the header view
let tableHeaderView = tableView.tableHeaderView
// Animate the height change
UIView.animate(withDuration: 0.6) {
tableHeaderView.frame = newFrame
self.tableView.tableHeaderView = tableHeaderView
})
Ответ 3
Выбранный ответ не помог мне. Пришлось сделать следующее:
[UIView animateWithDuration: 0.5f
animations: ^{
CGRect frame = self.tableView.tableHeaderView.frame;
frame.size.height = self.headerViewController.preferredHeight;
self.tableView.tableHeaderView.frame = frame;
self.tableView.tableHeaderView = self.tableView.tableHeaderView;
}];
Поистине своеобразная часть заключается в том, что это работает в одном представлении, но не в подклассе той же иерархии контроллера представления/представления.
Ответ 4
Я нашел окончательный и правильный способ добиться реальной анимации на tableHeaderView
s!
• Во-первых, если вы находитесь в Autolayout
, сохраните систему Margin
внутри своего заголовка. С Xcode 8 теперь это возможно (наконец!), Просто не устанавливайте никаких ограничений для любого из подзонов заголовка. Вам нужно будет определить правильные поля.
• Затем используйте beginUpdates
и endUpdates
, но поместите endUpdate
в блок анимации.
// [self.tableView setTableHeaderView:headerView]; // not needed if already there
[self.tableView beginUpdates];
CGRect headerFrame = self.tableView.tableHeaderView.bounds;
headerFrame.size.height = PLAccountHeaderErrorHeight;
[UIView animateWithDuration:0.2 animations:^{
self.tableView.tableHeaderView.bounds = headerFrame;
[self.tableView endUpdates];
}];
Примечание. Я только пробовал в iOS10, я опубликую обновление, когда будет загружен мой симулятор iOS9.
ИЗМЕНИТЬ
К сожалению, он не работает в iOS9, а также в iOS10: сам заголовок не изменяет его высоту, но заголовок заголовка, похоже, перемещается, как если бы границы заголовков менялись.
Ответ 5
Решение SWIFT 4 с другим заголовком
Если вам нужна анимация такого типа, я использовал это решение: (хотя в моем случае мне также пришлось немного поиграть с непрозрачностью объектов, поскольку я загружал другой совершенно другой заголовок)
fileprivate func transitionExample() {
let oldHeight = tableView.tableHeaderView?.systemLayoutSizeFitting(UILayoutFittingCompressedSize).height ?? 0
let newHeader = YourCustomHeaderView()
newHeader.hideElements() // If you want to play with opacity.
let smallHeaderFrame = CGRect(x: 0, y: 0, width: newHeader.frame.width, height: oldHeight)
let fullHeaderFrame = newHeader.frame
newHeader.frame = smallHeaderFrame
UIView.animate(withDuration: 0.4) { [weak self] in
self?.tableView.beginUpdates()
newHeader.showElements() // Only if have hided the elements before.
self?.tableView.tableHeaderView = newHeader
self?.tableView.tableHeaderView?.frame = fullHeaderFrame
self?.tableView.endUpdates()
}
}
Итак, в основном, все дело в смене рамки внутри замыкания .animate
. Обновления beging/end необходимы для перемещения и обновления других элементов tableView.
Ответ 6
Вот расширение Swift 5 UITableView для изменения headerView или изменения его высоты, анимированное с помощью AutoLayout
extension UITableView {
func animateTableHeader(view: UIView? = nil, frame: CGRect? = nil) {
self.tableHeaderView?.setNeedsUpdateConstraints()
UIView.animate(withDuration: 0.2, animations: {() -> Void in
let hView = view ?? self.tableHeaderView
if frame != nil {
hView?.frame = frame!
}
self.tableHeaderView = hView
self.tableHeaderView?.layoutIfNeeded()
}, completion: nil)
}
}
Ответ 7
Используйте приведенный ниже код, это работает
extension UITableView {
func hideTableHeaderView() -> Void {
self.beginUpdates()
UIView.animate(withDuration: 0.2, animations: {
self.tableHeaderView = nil
})
self.endUpdates()
}
func showTableHeaderView(header: UIView) -> Void {
let headerView = header
self.beginUpdates()
let headerFrame = headerView.frame
headerView.frame = CGRect()
self.tableHeaderView = headerView
UIView.animate(withDuration: 0.2, animations: {
self.tableHeaderView?.frame = headerFrame
self.tableHeaderView?.alpha = 0
self.endUpdates()
}, completion: { (ok) in
self.tableHeaderView?.alpha = 1
})
}
}