Reputation: 357
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
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
Reputation: 5151
Note that UITableView
inherits from UIScrollView
, so you can set pagingEnabled
to 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
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