2011-09-20 96 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.