UITableView,重新加载时滚动到底部?

时间:2011-02-25 00:40:35

标签: iphone objective-c cocoa-touch

我有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回调?

12 个答案:

答案 0 :(得分:120)

使用:

NSIndexPath* ipath = [NSIndexPath indexPathForRow: cells_count-1 inSection: sections_count-1];
[tableView scrollToRowAtIndexPath: ipath atScrollPosition: UITableViewScrollPositionTop animated: YES];

或者您可以手动指定部分索引(如果一个部分=> index = 0)。

答案 1 :(得分:37)

另一个解决方案是垂直翻转表格,并垂直翻转每个单元格:

初始化时将转换应用于UITableView:

tableview.transform = CGAffineTransformMakeScale(1, -1);

并在cellForRowAtIndexPath中:

cell.transform = CGAffineTransformMakeScale(1, -1);

这样您就不需要解决问题的方法,但是您需要更加关注contentInsets / contentOffsets和页眉/页脚交互。

答案 2 :(得分:33)

-(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];

}

答案 3 :(得分:9)

//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)

答案 4 :(得分:5)

这是另一种解决方案,在我的情况下效果很好,当细胞高度很大时。

- (void)scrollToBottom
{
    CGPoint bottomOffset = CGPointMake(0, _bubbleTable.contentSize.height - _bubbleTable.bounds.size.height);
    if ( bottomOffset.y > 0 ) {
        [_bubbleTable setContentOffset:bottomOffset animated:YES];
    }
}

答案 5 :(得分:4)

由于这可能是您经常想要使用的,我建议您在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)
            }
        }
    }
}

答案 6 :(得分:1)

扩展最好在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)
    }

}

答案 7 :(得分:1)

Swift 3

对于这里试图弄清楚如何解决这个问题的所有人来说,关键是在.layoutIfNeeded()之后调用.reloadData()方法:

tableView.reloadData()
tableView.layoutIfNeeded()
tableView.setContentOffset(CGPoint(x: 0, y: tableView.contentSize.height - tableView.frame.height), animated: false)

我正在使用UITableView中的多个部分,但效果很好。

答案 8 :(得分:1)

Foot 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)
            }
        }
    }
}

答案 9 :(得分:0)

这是最好的方式。

- (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];
}

答案 10 :(得分:0)

试试这段代码,它可以帮到你:

    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)
    })

答案 11 :(得分:0)

雨燕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_countsections_countself.dateSource.count等,相反,委托会更好。