2012-06-30 39 views
9

Tôi nhận được số UITableView được lấp đầy với số lượng hàng không xác định. Mỗi hàng chứa (ví dụ 3) hình ảnh và ứng dụng thu thập thông tin này từ một dịch vụ web.UITableView với tính năng cuộn vô hạn và tải chậm

Đối với UITableView Tôi đã triển khai cuộn vô hạn. Bất cứ khi nào bảng gần như đạt đến kết thúc của số lượng hàng hiện tại, tôi bắt đầu một cuộc gọi đến webservice, để tìm nạp 50 hàng dữ liệu tiếp theo. Tôi làm điều này trong phương pháp scrollViewDidScroll được gọi là UITableView.

- (void) scrollViewDidScroll:(UIScrollView *)scrollView 
{ 
    CGFloat actualPosition = scrollView.contentOffset.y; 

    float bottomOffset = 450; 
    if([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPad) 
     bottomOffset = 1000; 

    CGFloat contentHeight = scrollView.contentSize.height - bottomOffset; 
    if (actualPosition >= contentHeight && !_loading && !_cantLoadMore) 
    { 
     self.loading = YES; 

     _currentPage++; 

     NSMutableDictionary* dict = [[NSMutableDictionary alloc] init]; 
     [dict setObject:[NSNumber numberWithInt:_currentPage] forKey:@"page"]; 
     [dict setObject:[_category objectForKey:@"ID"] forKey:@"category"]; 

     [self performSelectorInBackground:@selector(getWallpapersInBackground:) withObject:dict]; 
    } 
} 

Hình ảnh trong các hàng của UITableView được tải chậm. Bất cứ khi nào một hàng được hiển thị, các hình ảnh được tải trong một chuỗi riêng biệt và các hàng được cập nhật khi hình ảnh được tải xuống hoàn toàn. Nguyên tắc tôi sử dụng để tải chậm, giống như Apple đề xuất trong tài liệu của họ. Hình ảnh cũng được thêm vào một địa phương NSDictionary, vì vậy tôi có thể tìm nạp nó khi hàng cuộn ra khỏi màn hình và quay lại (và hàng được tạo lại).

Vì lượng ảnh trong một lượt xem có thể lên đến 2000 - 3000, tôi cũng lưu hình ảnh vào đĩa và xóa hình ảnh từ NSDictionary khi chúng cách xa hơn X hàng. Khi người dùng cuộn xuống và lên một lần nữa sau xảy ra:

  1. hàng mới được hiển thị
  2. phương pháp bốc Lazy được gọi, mà kiểm tra nếu hình ảnh được trình bày trên đĩa hoặc rằng nó nên tải về nó.
  3. Khi hình ảnh được tải xuống hoặc tìm nạp từ đĩa, nó thực hiện một khóa mã, hiển thị hình ảnh trong hàng. Hình ảnh được tải xuống từ internet, cũng được lưu vào đĩa.
  4. UIImage được thêm vào NSDictionary để lưu bộ nhớ cache nhanh hơn các hình ảnh cần phải nằm trong tầm tay.
  5. Hình ảnh có hàng, 15 hàng hoặc xa hơn từ các hàng nhìn thấy được xóa khỏi NSDictionary, do các vấn đề về bộ nhớ (quá nhiều đối tượng UIImage trong số NSDictionary gây ra lỗi ngoài bộ nhớ).

Khi UITableView gần như đạt đến cuối cùng, sau đây xảy ra:

  1. UITableView gần như đạt đến cuối dòng hiện đang được nạp
  2. Gọi để webservice, với vô số hàng mới (50)
  3. Các hàng mới được thêm vào một mảng, được sử dụng cho phương thức numberOfItemsInSection.
  4. A reloadData được gọi để đảm bảo rằng UITableView điền với các hàng mới bổ sung.
  5. Hàng mới có chứa hình ảnh, thực hiện các bước được đề cập ở trên để tải hình ảnh một cách lười biếng.

Vì vậy, vấn đề tôi gặp phải là khi tôi thêm bản ghi mới từ dịch vụ web. Khi tôi gọi reloadData trên UITableView một số hình ảnh đang tải từ đĩa một lần nữa và một số nhấp nháy xảy ra khi di chuyển.

Tôi đang tìm giải pháp cho việc này.Tôi đã thử sử dụng insertItemsAtIndexPaths với số lượng hàng mới, để thêm chúng vào UITableView, nhưng điều này làm cho phương pháp tải lười biếng của tôi đã tải xuống hình ảnh (bởi vì bằng cách nào đó tất cả các ô được tạo tại thời điểm đó, ngay cả khi chúng không hiển thị, kiểm tra xem tế bào có thể nhìn thấy trong quá trình tạo ra mang lại kết quả không mong muốn, hình ảnh không tải, các ô trông lạ, vv).

Vì vậy, những gì tôi về cơ bản đang tìm kiếm là một giải pháp cho một UITableView cuộn vô tận, mà lười tải hình ảnh từ web/đĩa và mịn như ứng dụng hình ảnh. Vì hình ảnh đều được tải trong các chủ đề riêng biệt, tôi không hiểu tại sao việc cuộn không trơn tru như làn da của em bé.

+0

[KTPhotoBrowser] (https://github.com/kirbyt/KTPhotoBrowser) là một thư viện rất tốt để duyệt ảnh, tải xuống và lưu vào bộ nhớ cache. Bạn có thể sửa đổi nó để phù hợp với nhu cầu của bạn. – Hejazi

Trả lời

13

Tôi không chắc liệu mình có hoàn toàn lúng túng câu hỏi của bạn hay không, nhưng đây là một số điều tôi đã làm khi đối mặt với một vấn đề tương tự.

  • Tôi đã sử dụng -tableView:cellForRowAtIndexPath: làm tín hiệu để tải thêm dữ liệu từ web. Tôi đã chọn một số (trong trường hợp của tôi là 10), khi indexPath.row + 10 >= self.data.count tải thêm dữ liệu.

    • Dù sao thì tôi cũng cần gọi số -tableView:cellForRowAtIndexPath:.
    • Tôi đã không buộc gọi lại vào vòng lặp chặt chẽ hơn của -scrollViewDidScroll:.
  • Tôi được phân loại là UIImageView với lớp không đồng bộ tải hình ảnh mà tôi gọi là URLImageView.

    • Trong -tableView:cellForRowAtIndexPath:, tôi đã gán URL cho trường hợp URLImageView.
    • Bài tập đó đã gây ra hoạt động nền tải hoặc từ đĩa hoặc tải từ web.
    • Thao tác đã bị hủy, vì vậy tôi không tiếp tục làm việc trên một hình ảnh không còn cần tải nữa.

Tôi đã xem bảng với hàng trăm (nhưng không phải hàng nghìn) hình ảnh. Tôi chỉ có 2 hoặc 3 ô bảng trên màn hình cùng một lúc.

  • Tôi đã sử dụng -refreshData: nó hoạt động như một nhà vô địch.
  • Tôi thậm chí còn có URLImageView để mờ dần trong hình ảnh. Đó là một hiệu ứng rất đẹp.

Tôi hy vọng điều đó sẽ hữu ích.

+0

bạn có thể plz xây dựng một chút .. tôi đang đối mặt với cùng một vấn đề .. – Rakesh

+0

Tôi không chắc chắn những gì bạn muốn xây dựng? Trong '-tableView: cellForRowAtIndexPath:', 'if (indexPath.row + 10> = self.data.count) {[self.data loadNextChunkWithCompletion:^{[tableView reloadData]; }]; } ', trong đó' self.data' là một mô hình dữ liệu có dữ liệu được tải một phần và '-loadNextChunkWithCompletion:' là một phương thức tải phần tiếp theo của dữ liệu. –

2

để tránh nhấp nháy, hãy thử gọi số beginUpdates trên bàn, sau đó insertrowAtIndexPaths:withRowAnimations: và kết thúc bằng endUpdates.

Chúc may mắn.

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