How to scroll to the exact end of the UITableView?

前端 未结 16 2502
天涯浪人
天涯浪人 2020-12-07 18:48

I have a UITableView that is populated with cells with dynamic height. I would like the table to scroll to the bottom when the view controller is pushed from vi

相关标签:
16条回答
  • 2020-12-07 19:18

    I tried Umair's approach, however in UITableViews, sometimes there can be a section with 0 rows; in which case, the code points to an invalid index path (row 0 of an empty section is not a row).

    Blindly minusing 1 from the number of rows/sections can be another pain point, as, again, the row/section could contain 0 elements.

    Here's my solution to scrolling to the bottom-most cell, ensuring the index path is valid:

    extension UITableView {
        func scrollToBottomRow() {
            DispatchQueue.main.async {
                guard self.numberOfSections > 0 else { return }
    
                // Make an attempt to use the bottom-most section with at least one row
                var section = max(self.numberOfSections - 1, 0)
                var row = max(self.numberOfRows(inSection: section) - 1, 0)
                var indexPath = IndexPath(row: row, section: section)
    
                // Ensure the index path is valid, otherwise use the section above (sections can
                // contain 0 rows which leads to an invalid index path)
                while !self.indexPathIsValid(indexPath) {
                    section = max(section - 1, 0)
                    row = max(self.numberOfRows(inSection: section) - 1, 0)
                    indexPath = IndexPath(row: row, section: section)
    
                    // If we're down to the last section, attempt to use the first row
                    if indexPath.section == 0 {
                        indexPath = IndexPath(row: 0, section: 0)
                        break
                    }
                }
    
                // In the case that [0, 0] is valid (perhaps no data source?), ensure we don't encounter an
                // exception here
                guard self.indexPathIsValid(indexPath) else { return }
    
                self.scrollToRow(at: indexPath, at: .bottom, animated: true)
            }
        }
    
        func indexPathIsValid(_ indexPath: IndexPath) -> Bool {
            let section = indexPath.section
            let row = indexPath.row
            return section < self.numberOfSections && row < self.numberOfRows(inSection: section)
        }
    }
    
    0 讨论(0)
  • 2020-12-07 19:24

    To scroll to the end of your TableView you can use the following function, which also works for ScrollViews.

    It also calculates the safe area on the bottom for iPhone X and newer. The call is made from the main queue, to calculate the height correctly.

    func scrollToBottom(animated: Bool) {
        DispatchQueue.main.async {
            let bottomOffset = CGPoint(x: 0, y: self.contentSize.height - self.bounds.size.height + self.safeAreaBottom)
            
            if bottomOffset.y > 0 {
                self.setContentOffset(bottomOffset, animated: animated)
            }
        }
    }
    
    0 讨论(0)
  • 2020-12-07 19:25

    A little update of @Umair answer in case your tableView is empty

    func scrollToBottom(animated: Bool = true, delay: Double = 0.0) {
        let numberOfRows = tableView.numberOfRows(inSection: tableView.numberOfSections - 1) - 1
        guard numberOfRows > 0 else { return }
    
        DispatchQueue.main.asyncAfter(deadline: .now() + delay) { [unowned self] in
    
            let indexPath = IndexPath(
                row: numberOfRows,
                section: self.tableView.numberOfSections - 1)
            self.tableView.scrollToRow(at: indexPath, at: .bottom, animated: animated)
        }
    }
    
    0 讨论(0)
  • 2020-12-07 19:29

    If you used UINavigationBar with some height and UITableView in the UIView try it to subtract UINavigationBar height from UITableView's frame height . Cause your UITableView's top point same with UINavigationBar's bottom point so this affect your UITableView's bottom items to scrolling.

    Swift 3

    simpleTableView.frame = CGRect.init(x: 0, y: navigationBarHeight, width: Int(view.frame.width), height: Int(view.frame.height)-navigationBarHeight)
    
    0 讨论(0)
提交回复
热议问题