Chen Li Yong
Chen Li Yong

Reputation: 6097

How to scroll UITableView to a row *safely*?

Sometimes when I tried to scroll a tableview to a row, I can unexpectedly supply a nonexistent section/row. And then the app will crash.

self.tableView.scrollToRow(at: IndexPath(row: targetRow, section: targetSection), at: UITableViewScrollPosition.bottom, animated: true);

How can I make this scrolling process crash-safe? I mean, if I do supply a nonexistent section/row, I want UITableView just ignore it. Or how can I check whether a section/row is exist or not within a UITableView before I do the scroll? Thanks.

Upvotes: 15

Views: 6152

Answers (3)

chirag05k
chirag05k

Reputation: 61

Here's an another version with extension for UITableView that includes the scrollToRowSafely method

extension UITableView {
    func scrollToRowSafely(at indexPath: IndexPath, animated: Bool) {
        // Step 1: Check Data Availability
        guard indexPath.section < numberOfSections,
              indexPath.row < numberOfRows(inSection: indexPath.section) else {
            // Invalid index path, do not proceed with scrolling
            return
        }

        // Step 2: Perform on Main Thread
        DispatchQueue.main.async {

            // Step 3: Scroll Animation
            let scrollPosition: UITableView.ScrollPosition = .top

            // Step 4: Scroll to Row
            self.scrollToRow(at: indexPath, at: scrollPosition, animated: animated)
        }
    }
}

How to use it?

// Assuming you have a reference to your table view

tableView.scrollToRowSafely(at: IndexPath(row: 0, section: 0), animated: true)

Upvotes: 1

Aditya Srivastava
Aditya Srivastava

Reputation: 2650

Try this --

let indexPath = IndexPath(row: targetRow, section: targetSection)
if let _ = self.tableView.cellForRow(at: indexPath) {
 self.tableView.scrollToRow(at: indexPath, at: UITableViewScrollPosition.bottom, animated: true)
}

Upvotes: 13

RajeshKumar R
RajeshKumar R

Reputation: 15758

Use this UITableView extension to check whether a Indexpath is valid.

extension UITableView
{
    func indexPathExists(indexPath:IndexPath) -> Bool {
        if indexPath.section >= self.numberOfSections {
            return false
        }
        if indexPath.row >= self.numberOfRows(inSection: indexPath.section) {
            return false
        }
        return true
    }
}

Use like this

var targetRowIndexPath = IndexPath(row: 0, section: 0)
if table.indexPathExists(indexPath: targetRowIndexPath)
{
  table.scrollToRow(at: targetRowIndexPath, at: .bottom, animated: true)
}

Upvotes: 24

Related Questions