Madhubalan K
Madhubalan K

Reputation: 357

UITableView Pagination

My app has custom UITableView cells. I want to show only one cell at a time - next cell should show partially. In ScrollView you can set isPagingEnabled to YES.

But how can i do above in UITableView?

Thanks

Upvotes: 5

Views: 8628

Answers (3)

Joshua Wolff
Joshua Wolff

Reputation: 3342

Swift 5 basic version, but it does not work that well. I needed to customize it for my own use to make it work.

func scrollViewWillEndDragging(_ scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer<CGPoint>) {
    if let tv = scrollView as? UITableView {
        let path = tv.indexPathForRow(at: targetContentOffset.pointee)
        if path != nil {
            self.scrollToRow(at: path!, at: .top, animated: true)
        }
    }
}

Customized version

// If velocity is less than 0, then scrolling up
// If velocity is greater than 0, then scrolling down
if let tv = scrollView as? UITableView {
    let path = tv.indexPathForRow(at: targetContentOffset.pointee)
    if path != nil {
        // >= makes scrolling down easier but can have some weird behavior when scrolling up
        if velocity.y >= 0.0 {
            // Assumes 1 section
            // Jump to bottom one because user is scrolling down, and targetContentOffset is the very top of the screen
            let indexPath = IndexPath(row: path!.row + 1, section: path!.section)
            if indexPath.row < self.numberOfRows(inSection: path!.section) {
                self.scrollToRow(at: indexPath, at: .top, animated: true)
            }
         } else {
             self.scrollToRow(at: path!, at: .top, animated: true)
         }
    }
}

Upvotes: 0

J&#246;rn Eyrich
J&#246;rn Eyrich

Reputation: 5151

Note that UITableView inherits from UIScrollView, so you can set pagingEnabledto YES on the table view itself.

Of course, this will only work if all cells and the table view itself are of the same height.

If you want to always have a cell start at the top of the table view after scrolling, you could use a UIScrollViewDelegate and implement something like this.

- (void)scrollViewWillEndDragging:(UIScrollView *)scrollView
                     withVelocity:(CGPoint)velocity
              targetContentOffset:(inout CGPoint *)targetContentOffset
{
  UITableView *tv = (UITableView*)scrollView;
  NSIndexPath *indexPathOfTopRowAfterScrolling = [tv indexPathForRowAtPoint:
                                                       *targetContentOffset
                                                 ];
  CGRect rectForTopRowAfterScrolling = [tv rectForRowAtIndexPath:
                                             indexPathOfTopRowAfterScrolling
                                       ];
  targetContentOffset->y=rectForTopRowAfterScrolling.origin.y;
}

This lets you adjust at which content offset a scroll action will end.

Upvotes: 7

Dan Ray
Dan Ray

Reputation: 21893

I don't think I'd use a UITableView for this at all.

I think I'd use a UIScrollView with a tall stack of paged content. You could dynamically rebuild that content on scrolling activity, so you mimic the memory management of UITableView. UIScrollView will happily do vertical paging, depending on the shape of its contentView's frame.

In other words, I suspect it's easier to make a UIScrollView act like a table than to make a UITableView paginate like scroll view.

Upvotes: -1

Related Questions