问题
I'm facing with a simple but tedious problem. What I'm trying to do is make an UITableView to page like an UIScrollView but enabling paging doesn't help me so much because I can't set page size so the tableview scrolls exactly of its height so it shows rows 1...10 or 11...20 and so on. What I'd like instead is that no cell remains clipped above or under the view when I scroll (thus paging) without having a sort of fixed range of shown cells.
Thanks a lot
回答1:
More simple and more efficient :)
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate{
if(decelerate) return;
[self scrollViewDidEndDecelerating:scrollView];
}
- (void)scrollViewDidEndDecelerating:(UITableView *)tableView {
[tableView scrollToRowAtIndexPath:[tableView indexPathForRowAtPoint: CGPointMake(tableView.contentOffset.x, tableView.contentOffset.y+tableView.rowHeight/2)] atScrollPosition:UITableViewScrollPositionTop animated:YES];
}
回答2:
Simple but efficient:
- (void)scrollViewDidEndDecelerating:(UITableView *)tableView {
int tomove = ((int)tableView.contentOffset.y%(int)tableView.rowHeight);
if(tomove < tableView.rowHeight/2) [tableView setContentOffset:CGPointMake(0, tableView.contentOffset.y-tomove) animated:YES];
else [tableView setContentOffset:CGPointMake(0, tableView.contentOffset.y+(tableView.rowHeight-tomove)) animated:YES];
}
- (void)scrollViewDidEndDragging:(UITableView *)scrollView willDecelerate:(BOOL)decelerate {
if(decelerate) return;
[self scrollViewDidEndDecelerating:scrollView];
}
回答3:
Starting with k06a's answer, I've refined it a bit so it works more like the real paginated UITableView. The differences in behaviour are quite noticeable with full screen table rows. Even a mini-flick in either direction should scroll the table to the next page: I do this by checking velocity first.
- (void)scrollViewWillEndDragging:(UIScrollView *)scrollView
withVelocity:(CGPoint)velocity
targetContentOffset:(inout CGPoint *)targetContentOffset
{
CGFloat rowHeight = tableView.rowHeight;
int verticalOffset = ((int)targetContentOffset->y % (int)rowHeight);
if (velocity.y < 0)
{
targetContentOffset->y -= verticalOffset;
}
else if (velocity.y > 0)
{
targetContentOffset->y += (rowHeight - verticalOffset);
}
// No velocity, snap to closest page
else
{
if (verticalOffset < rowHeight / 2)
{
targetContentOffset->y -= verticalOffset;
}
else
{
targetContentOffset->y += (rowHeight - verticalOffset);
}
}
}
Note that additionally setting
self.tableView.decelerationRate = UIScrollViewDecelerationRateFast;
in viewDidLoad:
makes it closer to the real thing, but not quite.
I've been fiddling with setting even faster deceleration rates using the code shown here but I couldn't get it right.
回答4:
This works like real paging:
- (void)scrollViewWillEndDragging:(UIScrollView *)scrollView
withVelocity:(CGPoint)velocity
targetContentOffset:(inout CGPoint *)targetContentOffset
{
int tomove = ((int)targetContentOffset->y % (int)self.tableView.rowHeight);
if(tomove < self.tableView.rowHeight/2)
targetContentOffset->y -= tomove;
else
targetContentOffset->y += (self.tableView.rowHeight-tomove);
}
and make this in -viewDidLoad
:
self.tableView.decelerationRate = UIScrollViewDecelerationRateFast;
回答5:
And in Swift...
func scrollViewDidEndDragging(scrollView: UIScrollView, willDecelerate decelerate: Bool) {
if !decelerate {
self.scrollViewDidEndDecelerating(scrollView)
}
}
func scrollViewDidEndDecelerating(scrollView: UIScrollView) {
if let indexPathToScrollTo: NSIndexPath = self.tableView.indexPathForRowAtPoint(CGPointMake(self.tableView.contentOffset.x, self.tableView.contentOffset.y+tableView.rowHeight/2)) {
self.tableView.scrollToRowAtIndexPath(indexPathToScrollTo, atScrollPosition: UITableViewScrollPosition.Top, animated: true)
}
}
来源:https://stackoverflow.com/questions/2335249/uitableview-page-size-when-paging-enabled