2011-09-20 174 views
9

我想创建一个UITableView的日期,应该不是很令人兴奋,我知道。它从当前日期开始,但用户应该能够向下滚动(未来)以上(过去)尽可能远。这会导致可能的无限数量的行。那么创建这个有什么办法呢?永恒滚动UITableView

返回NSIntegerMax作为行数已经崩溃的应用程序,但即使它不会,这仍然不能考虑能够滚动。我当然可以开始,但最终会有一个最大值。

任何想法如何做或假这?我可以更新/重新加载表格,而不需要用户注意,所以我从来没有碰到边界?

SOLUTION:
我去@安德的建议,并与细胞的固定量做了一桌。但当用户滚动到固定单元格的边缘附近时,我不用重新加载它,而是在滚动停止时重新加载表格。为了适应用户在不停止的情况下滚动很长的距离,我只是将行数增加到了1000,并将ROW_CENTER常量设置为500.这是用于更新行的方法。

- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView 
{ 
    NSArray *visible = [self.tableView indexPathsForVisibleRows]; 
    NSIndexPath *upper = [visible objectAtIndex:0]; 
    NSIndexPath *lower = [visible lastObject]; 

    // adjust the table to compensate for the up- or downward scrolling 
    NSInteger upperDiff = ROW_CENTER - upper.row; 
    NSInteger lowerDiff = lower.row - ROW_CENTER; 

    // the greater difference marks the direction we need to compensate 
    NSInteger magnitude = (lowerDiff > upperDiff) ? lowerDiff : -upperDiff; 

    self.offset += magnitude; 
    CGFloat height = [self tableView:self.tableView heightForRowAtIndexPath:lower]; 
    CGPoint current = self.tableView.contentOffset; 
    current.y -= magnitude * height; 
    [self.tableView setContentOffset:current animated:NO]; 

    NSIndexPath *selection = [self.tableView indexPathForSelectedRow]; 
    [self.tableView reloadData]; 
    if (selection) 
    { 
     // reselect a prior selected cell after the reload. 
     selection = [NSIndexPath indexPathForRow:selection.row - magnitude inSection:selection.section]; 
     [self.tableView selectRowAtIndexPath:selection animated:NO scrollPosition:UITableViewScrollPositionNone]; 
    } 
} 

魔符当用户滚动表中的边缘没有停止,但与表视图bounces属性禁用,这只是感觉就像一个小故障,但完全可以接受的。一如既往,感谢StackOverflow!

+0

请在下面我的答案中试用一下代码。它使用一个简单的逻辑。 –

回答

5

当用户在tableview结尾附近滚动时,您应该建立固定数量的单元格并调整数据源。例如,您有一个包含51个日期(今天,25个未来和25个过去)的数组。当应用程序试图使靠近边界的一个细胞,重新配置阵列,并呼吁reloadData

+0

感谢您的建议。我正在尝试这个,但调用reloadData不会调整表视图的滚动位置(或contentOffset),所以它停止滚动。你的想法是什么?干杯。 – epologee

+0

恐怕没有停止滚动的情况下无法重新加载数据。在调用reloadData之后手动设置当前单元格的tableview的contentOffset ... – ender

+0

我选择了你的解决方案,但是把重载放在'scrollViewDidEndDecelerating:'方法中。这样重装就不会被用户注意到。将行数增加到合理的高数字(如1000)将处理大多数使用情况,而不会注意到任何故障。谢谢! – epologee

2

两个想法:

  1. 你真的需要一个UITableView?您可以使用UIScrollView,三个屏幕高。如果到达滚动结束,请布置您的内容并调整滚动位置。这给出了无限滚动的错觉。创建一些日期标签并在layoutSubviews:中排列它们不应该太费事。

  2. 如果你真的想坚持UITableView你可以考虑拥有两个UITableViews。如果您的第一个滚动到达临界点,则旋出一个线程并填充第二个线程。然后在某个时候,交换视图并手动触发滚动,以便用户不记下更改。这只是我头顶的一些想法。我还没有实现这样的东西,但我实现了无限的UIScrollView。

+0

好的建议。我一直在思考自己的第一个问题,但是我想坚持使用UITableView,因为所有的单元重用以及它感觉应该是一个表格:S。我会尝试一下UIScrollView,看看它有多好。谢谢! – epologee

3

你也可以看看在WWDC 2011年的“高级滚动型技术”的谈话,他们展示了如何创建一个UIScrollView其滚动下去。它开始约5分钟。在。

+0

谢谢,很好的提示,我有缓冲的地方。哦,非常感谢Trazzle人,多年来一直使用它! – epologee

0

我在另一篇文章中回答了这个问题:https://stackoverflow.com/a/15305937/2030823

包括:

https://github.com/samvermette/SVPullToRefresh

SVPullToRefresh处理逻辑时的UITableView到达底部。微调器会自动显示,并会触发回调块。您将业务逻辑添加到回调块。

#import "UIScrollView+SVInfiniteScrolling.h" 

// ... 

[tableView addInfiniteScrollingWithActionHandler:^{ 
    // append data to data source, insert new cells at the end of table view 
    // call [tableView.infiniteScrollingView stopAnimating] when done 
}]; 
0

这个问题已经被问:implementing a cyclic UITableView 我复制这个问题的答案在这里更容易,因为提问者没有选中我的答案。

UITableView与scrollViewDidScroll方法中的UIScrollView相同。

因此,它很容易模拟无限滚动。

  1. 双阵列,使得头部和尾部被连接在一起以模拟圆形工作台

  2. 使用我以下的代码,使加倍表和一倍表中的第二部分时,它们趋向的第一部分之间的用户切换以达到表格的开始或结束。

/* 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 (visualizing 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))); 
    } 

} 

附: - 我在我的一个名为NT Time Table(Lite)的应用程序中使用了此代码。如果你想预览,你可以看看应用程序:https://itunes.apple.com/au/app/nt-time-table-lite/id528213278?mt=8

如果你的表有时可能太短,在上面的方法开始时,你可以添加一个if逻辑退出,当数据计数是说例如少比9.