2011-09-20 41 views
9

Tôi đang cố gắng tạo một UITableView với ngày tháng, không nên rất thú vị, tôi biết. Nó bắt đầu vào ngày hiện tại, nhưng người dùng sẽ có thể cuộn xuống (tương lai) trở lên (quá khứ) theo ý muốn của họ. Điều này dẫn đến một số hàng có khả năng vô hạn. Vì vậy, cách để đi về việc tạo ra điều này là gì?Cuộn vĩnh viễn UITableView

Trả lại NSIntegerMax vì số lượng hàng đã treo ứng dụng, nhưng ngay cả khi không, vẫn không tính đến việc có thể cuộn lên. Tôi có thể bắt đầu một nửa cách của khóa học, nhưng cuối cùng có một tối đa.

Bất kỳ ý tưởng nào về cách thực hiện hoặc giả mạo điều này? Tôi có thể cập nhật/tải lại bảng bằng cách nào đó mà không có người dùng chú ý, vì vậy tôi không bao giờ chạy vào một biên giới?

GIẢI PHÁP:
Tôi đã đi với đề xuất của @ ender và tạo một bảng với số lượng cố định ô. Nhưng thay vì tải lại nó khi người dùng cuộn đến gần các cạnh của các ô cố định, tôi đã đi với tải lại bảng khi cuộn cuộn để dừng lại. Để phù hợp với một người dùng di chuyển khoảng cách lớn mà không dừng lại, tôi chỉ tăng số lượng hàng lên 1000, đặt hằng số ROW_CENTER lên 500. Đây là phương thức sẽ xử lý việc cập nhật các hàng.

- (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]; 
    } 
} 

Các phá vỡ kỳ diệu khi người dùng cuộn đến mép của bảng mà không dừng lại, nhưng với quan điểm bảng bounces sở hữu tàn tật, điều này chỉ đơn thuần là cảm giác giống như một trục trặc nhỏ, nhưng hoàn toàn chấp nhận được. Như mọi khi, cảm ơn StackOverflow!

+0

Vui lòng thử mã trong câu trả lời của tôi bên dưới. Nó sử dụng một logic đơn giản. –

Trả lời

5

Bạn nên thiết lập số lượng ô cố định và điều chỉnh nguồn dữ liệu của mình khi người dùng cuộn gần cuối chế độ xem bảng. Ví dụ, bạn có một mảng với 51 ngày (hôm nay, 25 tương lai và 25 quá khứ). Khi ứng dụng cố gắng để làm cho một tế bào gần một trong những biên giới, cấu hình lại mảng của bạn và gọi reloadData

+0

Cảm ơn bạn đã đề xuất. Tôi đang cố gắng này bây giờ, nhưng gọi reloadData sẽ không điều chỉnh vị trí di chuyển (hoặc contentOffset) của bảng xem, do đó, nó dừng di chuyển. Ý tưởng của bạn về điều đó là gì? Chúc mừng. – epologee

+0

Tôi e rằng không có cách nào để tải lại dữ liệu mà không cần dừng di chuyển. Có thể thiết lập thủ công contentOffset của tableview cho ô hiện tại sau khi gọi reloadData ... – ender

+0

Tôi đã chọn giải pháp của bạn, nhưng hãy nạp lại trong phương thức 'scrollViewDidEndDecelerating:'. Bằng cách đó, việc tải lại sẽ không được người dùng chú ý. Việc tăng số lượng hàng lên một con số cao hợp lý (như 1000) sẽ chăm sóc hầu hết các trường hợp sử dụng không nhận thấy bất kỳ sự cố nào. Cảm ơn! – epologee

2

Hai suy nghĩ:

  1. Bạn có thực sự cần một UITableView? Bạn có thể sử dụng UIScrollView, ba màn hình cao. Nếu đạt đến cuối cuộn, hãy bố trí nội dung của bạn và điều chỉnh vị trí cuộn. Điều này cho phép ảo tưởng về cuộn vô hạn. Tạo một số nhãn ngày và sắp xếp chúng trong layoutSubviews: không nên quá nhiều nỗ lực.

  2. Nếu bạn thực sự muốn gắn bó với UITableView bạn có thể nghĩ đến việc có hai UITableView. Nếu việc di chuyển trong trang đầu tiên của bạn đạt đến một điểm quan trọng, hãy bỏ qua một chuỗi và điền vào chuỗi thứ hai. Sau đó, tại một số điểm, trao đổi quan điểm và kích hoạt di chuyển theo cách thủ công để người dùng không lưu ý thay đổi. Đây chỉ là một ý tưởng từ đỉnh đầu tôi. Tôi đã không thực hiện một cái gì đó như thế này được nêu ra, nhưng tôi thực hiện UIScrollView vô hạn.

+0

Đề xuất tốt. Tôi đã suy nghĩ về bản thân mình đầu tiên, nhưng tôi muốn dính vào UITableView vì tất cả các tế bào tái sử dụng và thực tế là nó cảm thấy như nó phải là một bảng: S. Tôi sẽ thử UIScrollView để xem nó hoạt động tốt như thế nào. Cảm ơn! – epologee

3

Bạn cũng có thể xem qua bài nói chuyện "Kỹ thuật xem cuộn nâng cao" của WWDC 2011. Họ đã chỉ ra cách bạn tạo UIScrollView cuộn vô thời hạn. Nó bắt đầu vào khoảng 5 phút. trong.

+0

Cảm ơn, lời khuyên tốt, tôi đã buffered một nơi nào đó. Oh và cảm ơn rất nhiều cho người đàn ông Trazzle, sử dụng nó trong nhiều năm! – epologee

0

Tôi đã trả lời câu hỏi này trong bài khác: https://stackoverflow.com/a/15305937/2030823

Bao gồm:

https://github.com/samvermette/SVPullToRefresh

SVPullToRefresh xử lý logic khi UITableView đạt phía dưới. Một spinner được hiển thị tự động và một khối gọi lại được kích hoạt. Bạn thêm vào logic nghiệp vụ của mình vào khối gọi lại.

#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

Câu hỏi này đã được hỏi: implementing a cyclic UITableView Tôi sao chép câu trả lời ở đây để làm cho nó dễ dàng hơn bởi vì Người hỏi đã không đánh dấu câu trả lời của tôi.

UITableView giống với UIScrollView trong phương thức scrollViewDidScroll.

Vì vậy, thật dễ dàng để mô phỏng cuộn vô hạn.

  1. gấp đôi so với mảng để đầu và đuôi được nối với nhau để thi đua bàn tròn

  2. sử dụng đoạn mã sau của tôi để thực hiện chuyển đổi sử dụng giữa phần 1 của bảng đã tăng gấp đôi và phần thứ 2 của bảng nhân đôi khi họ có xu hướng để đạt được sự bắt đầu hoặc kết thúc của bảng.

:

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

} 

T.B. - Tôi đã sử dụng mã này trên một trong các ứng dụng của tôi có tên NT Time Table (Lite). Nếu bạn muốn xem trước, bạn có thể xem ứng dụng: https://itunes.apple.com/au/app/nt-time-table-lite/id528213278?mt=8

Nếu bảng của bạn đôi khi có thể quá ngắn, ở đầu phương pháp trên, bạn có thể thêm logic nếu thoát khi số liệu ít hơn hơn 9.

Các vấn đề liên quan