简体   繁体   English

UITableView 滚动到底部

[英]UITableView scroll to bottom

I have this line of code:我有这行代码:

tableView.contentOffset = CGPointMake(0.0f, 10000000.0f);

The content size is a lot less than the 10000000.0f , but the UITableView still does not scroll to the bottom.内容大小比10000000.0f小很多,但 UITableView 仍然没有滚动到底部。 How can I do it?我该怎么做?

Scrolling to tableViewCell ?滚动到tableViewCell

//for instance, you have 15 cells
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:14 inSection:0];
[self.tableView scrollToRowAtIndexPath:indexPath
                      atScrollPosition:UITableViewScrollPositionTop
                              animated:YES];

You can create an extension of UIScrollView , and use it for any instance of UIScrollView, UITableView or UICollectionView.您可以创建UIScrollView的扩展,并将其用于 UIScrollView、UITableView 或 UICollectionView 的任何实例。

extension UIScrollView {

    func scrollToBottom(animated: Bool) {
        var y: CGFloat = 0.0
        let HEIGHT = self.frame.size.height
        if self.contentSize.height > HEIGHT {
            y = self.contentSize.height - HEIGHT
        }
        self.setContentOffset(CGPointMake(0, y), animated: animated)
    }
}

Whenever the content size if greater than scroll view's height, it will scroll accordingly to the correct position.每当内容大小大于滚动视图的高度时,它将相应地滚动到正确的位置。 This method works with AutoLayout also.此方法也适用于 AutoLayout。

Swift 5, iOS 12 tested Swift 5,iOS 12 测试

👇 This code works perfectly for UITableView , even if there are sections with 0 elements (which will crash in every other solution I saw on the Internet) 👇这段代码非常适合UITableView ,即使有 0 个元素的部分(这会在我在互联网上看到的所有其他解决方案中崩溃)

extension UITableView {
    func scrollTableViewToBottom(animated: Bool) {
        guard let dataSource = dataSource else { return }

        var lastSectionWithAtLeasOneElements = (dataSource.numberOfSections?(in: self) ?? 1) - 1

        while dataSource.tableView(self, numberOfRowsInSection: lastSectionWithAtLeasOneElements) < 1 {
            lastSectionWithAtLeasOneElements -= 1
        }

        let lastRow = dataSource.tableView(self, numberOfRowsInSection: lastSectionWithAtLeasOneElements) - 1

        guard lastSectionWithAtLeasOneElements > -1 && lastRow > -1 else { return }

        let bottomIndex = IndexPath(item: lastRow, section: lastSectionWithAtLeasOneElements)
        scrollToRow(at: bottomIndex, at: .bottom, animated: animated)
    }
}

fixed version from Kevin in this topic, preventing infinite scroll for tableView with 0 items: Source: https://stackoverflow.com/a/59470799/9763761本主题中 Kevin 的固定版本,防止无限滚动0项的 tableView:来源: https : //stackoverflow.com/a/59470799/9763761

func scrollToBottom(animated: Bool) {
    guard let dataSource = dataSource else { return }
    var lastSectionWithAtLeastOneElement = (dataSource.numberOfSections?(in: self) ?? 1) - 1
    while dataSource.tableView(self, numberOfRowsInSection: lastSectionWithAtLeastOneElement) < 1 && lastSectionWithAtLeastOneElement > 0 {
        lastSectionWithAtLeastOneElement -= 1
    }
    let lastRow = dataSource.tableView(self, numberOfRowsInSection: lastSectionWithAtLeastOneElement) - 1
    guard lastSectionWithAtLeastOneElement > -1 && lastRow > -1 else { return }
    let bottomIndex = IndexPath(item: lastRow, section: lastSectionWithAtLeastOneElement)
    scrollToRow(at: bottomIndex, at: .bottom, animated: animated)
}

👇 This code works for UIScrollView , but won't work for UITableView that have more cells then one screen can fit, because of Apple's weird internal implementation of UITableViewController : 👇此代码为UIScrollView ,但不工作UITableView有更多的细胞,然后在一个屏幕可以适应,因为苹果的怪异内部实现的UITableViewController

extension UIScrollView {
    func scrollToBottom(animated: Bool) {
        guard contentSize.height > bounds.size.height else { return }

        let bottomOffset = CGPoint(x: 0, y: contentSize.height - bounds.size.height + contentInset.bottom)
        setContentOffset(bottomOffset, animated: true)
    }
}

Unfortunately I don't yet have enough rep to comment, but vol's answer has 1 mistake in it which causes an infinite while loop when you call it on a tableview with 0 items, aside from that it works perfectly!不幸的是,我还没有足够的代表来发表评论,但是 vol 的回答中有 1 个错误,当您在具有 0 个项目的 tableview 上调用它时会导致无限的 while 循环,除此之外它工作得很好! Corrected code below:更正以下代码:

func scrollToBottom(animated: Bool) {
    guard let dataSource = dataSource else { return }
    var lastSectionWithAtLeastOneElement = (dataSource.numberOfSections?(in: self) ?? 1) - 1
    while dataSource.tableView(self, numberOfRowsInSection: lastSectionWithAtLeastOneElement) < 1 && lastSectionWithAtLeastOneElement > 0 {
        lastSectionWithAtLeastOneElement -= 1
    }
    let lastRow = dataSource.tableView(self, numberOfRowsInSection: lastSectionWithAtLeastOneElement) - 1
    guard lastSectionWithAtLeastOneElement > -1 && lastRow > -1 else { return }
    let bottomIndex = IndexPath(item: lastRow, section: lastSectionWithAtLeastOneElement)
    scrollToRow(at: bottomIndex, at: .bottom, animated: animated)
}

try this code:试试这个代码:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM