how to implement cyclic scrolling on tableview

2019-02-12 22:01发布

问题:

Could you please help me with circular scrolling in tableview please.

I want that if I scroll down tableview, the rows should go in the reverse way -- it should appear that move back around (bottom rows go around and now come back down from the top) i.e, cyclic scrolling basically.

How can I do so. Any suggestions please.

Thanx in advance.

回答1:

You could "fake" the cyclic scrolling repeating the same cells all over again. In the numberOfRowsInSection method, return n times the actual number of rows. Make sure n is big enough.

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    return numberOfActualRows*100;
}

Then in the cellForRowAtIndexPath method (and elsewhere) use the mod operator (%) to return the proper cell.

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    NSUInteger actualRow = indexPath.row % numberOfActualRows;
    ...
}

You may want to hide the sroll indicator.

self.tableView.showsVerticalScrollIndicator = NO;

You may also want to scoll the table view to the middle before you display the table so scrolling backwards works fine.

[self.tableView scrollToRowAtIndexPath: [NSIndexPath indexPathForRow:[self tableView:self.tableView numberOfRowsInSection:0]/2 inSection:0]  atScrollPosition:UITableViewScrollPositionTop animated:NO];

Of course, the user would eventually hit the bottom or the top if he/she kept scrolling over and over.



回答2:

This question has already been asked: implementing a cyclic UITableView I'm copying that answer here to make it easier because the asker hasn't ticked my answer.

UITableView is same as UIScrollView in scrollViewDidScroll method.

So, its easy to emulate infinite scrolling.

  1. double the array so that head and tail are joined together to emulate circular table

  2. use my following code to make user switch between 1st part of doubled table and 2nd part of doubled table when they tend to reach the start or the end of the table.

:

/* To emulate infinite scrolling...

The table data was doubled to join the head and tail: (suppose table had 1,2,3,4)
1 2 3 4|1 2 3 4 (actual data doubled)
---------------
1 2 3 4 5 6 7 8 (visualising joined table in eight parts)

When the user scrolls backwards to 1/8th of the joined table, user is actually at the 1/4th of actual data, so we scroll instantly (we take user) to the 5/8th of the joined table where the cells are exactly the same.

Similarly, when user scrolls to 6/8th of the table, we will scroll back to 2/8th where the cells are same. (I'm using 6/8th when 7/8th sound more logical because 6/8th is good for small tables.)

In simple words, when user reaches 1/4th of the first half of table, we scroll to 1/4th of the second half, when he reaches 2/4th of the second half of table, we scroll to the 2/4 of first half. This is done simply by subtracting OR adding half the length of the new/joined table.

 Written and posted by Anup Kattel. Feel free to use this code. Please keep these comments if you don't mind.
*/


-(void)scrollViewDidScroll:(UIScrollView *)scrollView_ 
{  

    CGFloat currentOffsetX = scrollView_.contentOffset.x;
    CGFloat currentOffSetY = scrollView_.contentOffset.y;
    CGFloat contentHeight = scrollView_.contentSize.height;

    if (currentOffSetY < (contentHeight / 8.0)) {
    scrollView_.contentOffset = CGPointMake(currentOffsetX,(currentOffSetY + (contentHeight/2)));
    }
   if (currentOffSetY > ((contentHeight * 6)/ 8.0)) {
       scrollView_.contentOffset = CGPointMake(currentOffsetX,(currentOffSetY - (contentHeight/2)));
    }

}

P.S. - I've used this code on one of my apps called NT Time Table (Lite). If you want the preview, you can check out the app: https://itunes.apple.com/au/app/nt-time-table-lite/id528213278?mt=8

If your table can sometimes be too short, at the beginning of the above method you can add a if logic to exit when data count is say for example less than 9.



回答3:

I haven't done this myself, but you could try the approach you'd use with a UIScrollView to implement cycling scrolling of views (after all UITableView is a subclass of UIScrollView).

I would do as follows:

  1. Create a UITableView with an arbitrary number of cells (at least 7 but will need more to prevent fast scrolling bumping at the end)
  2. Position your UITableView so the centre cell is visible
  3. Maintain a pointer to the index of the cell you are looking to display
  4. In your cellForRowAtIndexPath: use your pointer to as an offset and add the row to it to get the cell that you want
  5. When the UITableView has stopped moving (your UITableViewDelegate can serve as UIScrollViewDelegate so you can use scrollViewDidEndDecelerating). Set your offset index to the current cell, move the table view back to the centre cell without animation and reload the data.

The issue you will have is if the user keeps scrolling without stopping they will eventually hit the bumpers as the number of cells in the table is reached.

Hope this helps, and please post back if you get this working and it looks at all reasonable.

Regards

Dave



回答4:

This is very much difficult to implement. However, take a look at the ScorllingMadness, which shows the demo of nested (cyclic) pages in a scroll-view.

You need to use the similar kind of trick here as UITableView is a subclass of UIScrollView.