2011-02-11 21 views
7

Tôi có UITableView với danh sách các mục, mỗi mục có hình ảnh riêng. Tôi nghĩ dự án mẫu LazyTableImages của Apple sẽ hoàn hảo để học hỏi và sử dụng để thực hiện cùng một quá trình tải xuống hình ảnh một cách không đồng bộ, sau khi dữ liệu danh sách gốc được truy xuất.Câu hỏi về mẫu LazyTableImages của Apple - Không hoạt động chính xác như cửa hàng ứng dụng

Phần lớn, nó hoạt động khá tốt, ngoại trừ tôi đã nhận thấy sự khác biệt tinh vi về hành vi, giữa ứng dụng mẫu này và cách cửa hàng ứng dụng thực tế tải xuống hình ảnh.

Nếu bạn khởi chạy mẫu LazyTableImages, sau đó cuộn nhanh xuống, bạn sẽ thấy hình ảnh không được hiển thị cho đến khi sau khi cuộn đi đến điểm dừng hoàn toàn.

Bây giờ, nếu bạn làm cùng một thử nghiệm với danh sách các mục trong cửa hàng ứng dụng thực tế, bạn sẽ thấy hình ảnh bắt đầu hiển thị ngay khi các mục mới được xem, ngay cả khi cuộn chưa dừng .

Tôi đang cố gắng để đạt được những kết quả tương tự, nhưng cho đến nay tôi không thực hiện bất kỳ tiến bộ nào. Có ai có bất kỳ ý tưởng về làm thế nào để làm điều này?

Cảm ơn!

Trả lời

10

Tôi có vách ngăn mà không ai có thể trả lời này ...

Vì vậy, tôi cuối cùng đã tìm ra cách để đạt được sự chính xác cùng hiệu quả được sử dụng trong các cửa hàng ứng dụng thực tế, liên quan đến cách thức các biểu tượng được tải xuống/hiển thị.

Lấy dự án mẫu LazyTableImages và thực hiện một vài sửa đổi đơn giản.

  1. Đi vào bộ điều khiển xem gốc và loại bỏ tất cả các kiểm tra liên quan đến là bảng di chuyển và/hoặc giảm tốc trong cellForRowAtIndexPath

  2. Hủy bỏ tất cả các cuộc gọi đến loadImagesForOnScreenRows, và do đó loại bỏ phương pháp đó là tốt.

  3. Đi vào IconDownload.m và thay đổi phương thức startDownload thành không thực hiện downlaod hình ảnh không đồng bộ, nhưng thay vào đó hãy tải xuống đồng bộ hóa trên chuỗi nền.Hủy bỏ tất cả các mã trong startDownload, và thêm những điều sau đây, vì vậy nó trông như thế này:

 

- (void)startDownload 
{ 
    NSOperationQueue *queue = [NSOperationQueue new]; 
    NSInvocationOperation *operation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(loadImage) object:nil]; 

    [queue addOperation:operation]; 

    [operation release]; 
    [queue release]; 
} 
 

Sau đó, thêm một LoadImage, như thế này:

 

- (void)loadImage 
{ 
    NSData *imageData = [[NSData alloc] initWithContents OfURL:[NSURL URLWithString:appRecord.imageURLString]]; 
    self.apprecord.appIcon = [UIImage imageWithData:imageData]; 
    [imageData release]; 

    [self performSelectorOnMainThread:@selector(notifyMainThread) withObject:nil waitUntilDone:NO]; 
} 
 

Sau đó, thêm notifyMainThread như thế này :

 

- (void)notifyMainThread 
{ 
    [delegate appImageDidLoad:self.indexPathInTableView]; 
} 
 

Xong! Chạy ứng dụng này và bạn sẽ thấy hành vi lưu trữ ứng dụng chính xác, không phải chờ đợi để yêu cầu tải xuống hình ảnh cho đến khi cuộn dừng và không chờ đợi hình ảnh hiển thị cho đến khi cuộn dừng hoặc cho đến khi người dùng xóa ngón tay khỏi màn hình.

Hình ảnh được tải xuống ngay khi ô sẵn sàng hiển thị và hình ảnh được hiển thị ngay sau khi được tải xuống, thời gian.

Xin lỗi vì bất kỳ lỗi chính tả, tôi không dán này từ ứng dụng của tôi, tôi đã gõ nó trong, vì tôi xa mac của tôi ngay bây giờ ...

Dù sao, tôi hy vọng điều này sẽ giúp tất cả các bạn. ..

+0

Tuyệt vời! Cảm ơn bạn đã đăng bài này! –

+0

Tôi đánh giá cao nỗ lực của bạn trong việc cải thiện ví dụ của Apple. Giải pháp của bạn hoạt động một phần. Di chuyển các đại biểu nên ** KHÔNG ** bị loại bỏ, hoặc trình điều khiển xem của bạn không biết khi nào bắt đầu tải xuống các biểu tượng. 'LoadImagesForOnScreenRows' cũng nên được gọi trong' viewDidLoad' hoặc 'viewDidAppear', phụ thuộc vào cách sử dụng. – Raptor

+0

Đẹp, nhưng nó thay đổi toàn bộ mã mẫu. Nó không còn sử dụng NSURLConnection nữa. – yosh

0

Kiểm tra UIScrollViewDelegate. Tôi đã thực hiện một cái gì đó như thế này bằng cách nghe scrollViewDidScroll:, tính tốc độ di chuyển (bằng cách kiểm tra contentOffset so với lần cuối cùng được ghi lại contentOffset, chia cho sự chênh lệch về thời gian) và bắt đầu tải hình ảnh khi tốc độ giảm xuống dưới một ngưỡng nhất định. (Bạn cũng có thể đạt được điều gì đó tương tự với số scrollViewDidEndDragging:willDecelerate: của UIScrollViewDelegate).

Tất nhiên, bạn không phải kiểm tra tốc độ; bạn chỉ có thể tải hình ảnh trên UITableViewDelegate 's tableView:willDisplayCell:forRowAtIndexPath: bất cứ khi nào bạn nhìn thấy một ô mới, nhưng tôi thấy rằng nếu người dùng lật qua tấn ô, bạn không cần phải bận tâm cho đến khi bạn thấy rằng họ sẽ làm chậm xuống để duyệt.

+0

Tôi đã thử cách này. Tôi đã xác minh rằng các cuộc gọi để tải xuống các ảnh mục mới được hiển thị đang diễn ra ngay lập tức. Tuy nhiên, connectionDidFinishLoading: không bao giờ được gọi cho đến khi di chuyển đến một điểm dừng hoàn toàn. Tôi thực sự bối rối bởi hành vi này ... – bpatrick100

+0

Một cách khác để mô tả hành vi ứng dụng mẫu, là nếu bạn vuốt danh sách lên, nhưng không thả ngón tay của bạn (giữ nó trên màn hình), bạn sẽ thấy rằng hình ảnh không hiển thị. Sau đó, ngay sau khi bạn thả ngón tay ra, hình ảnh sẽ hiển thị. Nó có vẻ giống như hành vi đơn luồng. Tôi tự hỏi nếu đó là toàn bộ vấn đề ở đây. Tôi tự hỏi nếu tôi cần phải đặt một cách rõ ràng từng cuộc gọi tải xuống hình ảnh vào chủ đề của riêng họ ... – bpatrick100

+0

Sẽ đủ để chỉ phân bổ một chuỗi cho tất cả các cuộc gọi tải xuống của bạn. Đối với các kết nối nói chung, tôi khuyên bạn nên ASIHTTPRequest (http://allseeing-i.com/ASIHTTPRequest/) – kevboh

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