Подтвердить что ты не робот

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, который я мог бы использовать?

4b9b3361

Ответ 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 и т.д. Вместо этого делегат будет лучше.