UITableView page size when paging enabled

2019-03-08 21:29发布

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

5条回答
欢心
2楼-- · 2019-03-08 21:52

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楼-- · 2019-03-08 21:52

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楼-- · 2019-03-08 21:54

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)
    }
}
查看更多
The star\"
5楼-- · 2019-03-08 21:58

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;
查看更多
Root(大扎)
6楼-- · 2019-03-08 22:06

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];
}
查看更多
登录 后发表回答