UITableView, прокрутите вниз до перезагрузки?
У меня есть UITableView
с cells
, которые динамически обновляются. Все отлично работает, когда вызывается tableview.reload
(см. Ниже), чтобы обновить cells
в таблице. Мне бы хотелось, чтобы таблица прокручивалась вниз, чтобы отображать новые записи.
- (void)reloadTable:(NSNotification *)notification {
NSLog(@"RELOAD TABLE ...");
[customTableView reloadData];
// Scroll to bottom of UITable here ....
}
Я планировал использовать scrollToRowAtIndexPath:atScrollPosition:animated:
, но потом заметил, что у меня нет доступа к indexPath
.
Кто-нибудь знает, как это сделать, или обратного вызова delegate
, который я мог бы использовать?
Ответы
Ответ 1
Использование:
NSIndexPath* ipath = [NSIndexPath indexPathForRow: cells_count-1 inSection: sections_count-1];
[tableView scrollToRowAtIndexPath: ipath atScrollPosition: UITableViewScrollPositionTop animated: YES];
Или вы можете указать индекс раздела вручную (если один раздел = > index = 0).
Ответ 2
Другое решение - перевернуть таблицу по вертикали и перевернуть каждую ячейку по вертикали:
Примените преобразование к UITableView при инициализации:
tableview.transform = CGAffineTransformMakeScale(1, -1);
и в cellForRowAtIndexPath:
cell.transform = CGAffineTransformMakeScale(1, -1);
Таким образом вам не нужны обходные пути для прокрутки, но вам нужно будет немного подумать о contentInsets/contentOffsets и взаимодействиях header/footer.
Ответ 3
-(void)scrollToBottom{
[self.tableView scrollRectToVisible:CGRectMake(0, self.tableView.contentSize.height - self.tableView.bounds.size.height, self.tableView.bounds.size.width, self.tableView.bounds.size.height) animated:YES];
}
Ответ 4
//In swift
var iPath = NSIndexPath(forRow: self.tableView.numberOfRowsInSection(0)-1,
inSection: self.tableView.numberOfSections()-1)
self.tableView.scrollToRowAtIndexPath(iPath,
atScrollPosition: UITableViewScrollPosition.Bottom,
animated: true)
Ответ 5
Это еще одно решение, хорошо работающее в моем случае, когда высота ячейки велика.
- (void)scrollToBottom
{
CGPoint bottomOffset = CGPointMake(0, _bubbleTable.contentSize.height - _bubbleTable.bounds.size.height);
if ( bottomOffset.y > 0 ) {
[_bubbleTable setContentOffset:bottomOffset animated:YES];
}
}
Ответ 6
Поскольку это то, что вы, возможно, захотите использовать очень часто, я предлагаю вам создать расширение класса в UITableView:
extension UITableView {
func scrollToBottom(animated: Bool = true) {
let section = self.numberOfSections
if section > 0 {
let row = self.numberOfRowsInSection(section - 1)
if row > 0 {
self.scrollToRowAtIndexPath(NSIndexPath(forRow: row - 1, inSection: section - 1), atScrollPosition: .Bottom, animated: animated)
}
}
}
}
Ответ 7
Свифт 3
Для всех, кто здесь пытается выяснить, как решить эту проблему, ключом является вызов .layoutIfNeeded()
после .reloadData()
:
tableView.reloadData()
tableView.layoutIfNeeded()
tableView.setContentOffset(CGPoint(x: 0, y: tableView.contentSize.height - tableView.frame.height), animated: false)
Я работал с несколькими разделами в UITableView
и он работал хорошо.
Ответ 8
Расширение лучше делать в UIScrollView вместо UITableView, таким образом он работает на scrollView, tableView, collectionView (вертикальный), UIWebView (внутренний просмотр прокрутки) и т.д.
public extension UIScrollView {
public func scrollToBottom(animated animated: Bool) {
let rect = CGRectMake(0, contentSize.height - bounds.size.height, bounds.size.width, bounds.size.height)
scrollRectToVisible(rect, animated: animated)
}
}
Ответ 9
Fot Swift 5
extension UITableView {
func scrollToBottom(animated: Bool = true) {
let section = self.numberOfSections
if section > 0 {
let row = self.numberOfRows(inSection: section - 1)
if row > 0 {
self.scrollToRow(at: IndexPath(row: row-1, section: section-1), at: .bottom, animated: animated)
}
}
}
}
Ответ 10
Это лучший способ.
- (void)scrollToBottom
{
CGFloat yOffset = 0;
if (self.tableView.contentSize.height > self.tableView.bounds.size.height) {
yOffset = self.tableView.contentSize.height - self.tableView.bounds.size.height;
}
[self.tableView setContentOffset:CGPointMake(0, yOffset) animated:NO];
}
Ответ 11
попробуйте этот код, он может помочь вам:
self.tableView.reloadData()
DispatchQueue.main.asyncAfter(deadline: DispatchTime.now()+0.1, execute: {
let indexPath = IndexPath(row: self.dateSource.count-1, section: 0)
self.tableView.scrollToRow(at: indexPath, at: UITableViewScrollPosition.bottom, animated: true)
})
Ответ 12
Swift 5
func scrollToBottom() {
let section = self.tableView.numberOfSections
let row = self.tableView.numberOfRows(inSection: self.tableView.numberOfSections - 1) - 1;
guard (section > 0) && (row > 0) else{ // check bounds
return
}
let indexPath = IndexPath(row: row-1, section: section-1)
self.tableView.scrollToRow(at: indexPath, at: .top, animated: true)
}
Я не согласен с тем, что мы должны использовать cells_count
, sections_count
, self.dateSource.count
и т.д. Вместо этого делегат будет лучше.