2012-07-20 77 views
1

下載幾張圖片並將它們加載到UITableViewCell中的UIImageView中的最佳做法是什麼?特別是,我應該下載後調整/更換UIImageview,或者我應該調整圖像的大小以適應UIImageView。請注意,調整大小/替換UIImageView也會調整/替換UITableViewCell。它會導致任何問題?在UITableView中加載幾張圖片

回答

0

UITableViewCell中延遲加載圖像的常見做法是使用通知回調讓UITableViewCell知道何時已收到圖像。

從本質上說,你要創建的UIImageView一個子類,有一個IMAGEURL字段,改變的情況下,觸發關閉的圖像的請求,並用它來代替標準UIImageView

接口在UIImageView的子類:

@property (nonatomic, copy) NSString *imageURL; 

實現了UIImageView的子類:

//synthesize property 
@synthesize imageURL = _imageURL; 

- (void)setImageURL:(NSString *)imageURL { 
    if(_imageURL) 
     [[NSNotificationCenter defaultCenter] removeObserver:self name:_imageURL object:nil]; 
    _imageURL = [imageURL copy]; 
    //if imageURL is valid... 
    if(_imageURL.length) { 
     [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didReceiveImage:) name:_imageURL object:nil]; 
     //fire off some asynchronous image fetch 
     //when the image fetch completes, sent off a notification using the imageURL as the notification name 
     //It's up to you to create the implementation for this yourself 
     ... [MyImageManager fetchImage:_imageURL notificationName:_imageURL]; 
    } 
} 

- (void)didReceiveImage:(NSNotification*)notification 
{ 
    //handle your received image here 
    if([notification.object isKindOfClass:[UIImage class]]) 
    { 
     self.myCustomImageView.image = notification.object; 
    } 
} 

然後在日ËUITableViewCell類,當你重寫prepareForReuse:

- (void)prepareForReuse { 
    [super prepareForReuse]; 
    self.myCustomImageView.imageURL = nil; 
    self.myCustomImageView.image = nil; 
    //do the rest of your prepareForReuse here: 
    ... 
} 

現在,只要圖像VS中的ImageView的大小調整的整體調整大小,你應該做的是獨自離開的ImageView大小,並使用contentMode屬性來處理所得圖像的不同尺寸。您possible values是:

UIViewContentModeScaleToFill, 
UIViewContentModeScaleAspectFit, 
UIViewContentModeScaleAspectFill, 
UIViewContentModeRedraw, 
UIViewContentModeCenter, 
UIViewContentModeTop, 
UIViewContentModeBottom, 
UIViewContentModeLeft, 
UIViewContentModeRight, 
UIViewContentModeTopLeft, 
UIViewContentModeTopRight, 
UIViewContentModeBottomLeft, 
UIViewContentModeBottomRight, 

其中每一種都有自己各自的結果 - 你可能會想使用UIViewContentModeScaleAspectFit,因爲這將重新大小的圖像以適合ImageView的,不扭曲它 - 這可能會留下空利潤率imageView的大小或頂部/底部。 Aspect fill會做類似的事情,只是它會調整圖像的大小,使其足夠大以填充整個imageView,並可能切斷圖像的邊或頂部/底部。要填充的比例將僅延伸圖像以填充imageView。

+0

那麼你是說每當我得到圖像時調整每個單元格是否可以? – fatih 2012-07-20 16:39:20

+0

實際設置圖像時,不需要調整UIImageView的大小。你可以做的是設置imageView的'contentMode'。我會編輯我的答案來反映這一點。 – CrimsonDiego 2012-07-20 16:43:54

+0

正如你在最後一段中指出的那樣,如果我不調整imageview的大小,這可能會留下一些空白,這是不可取的。 – fatih 2012-07-20 17:07:20

3

一對夫婦的想法:

什麼是下載一些圖片,並加載它們中的每一個UIImageView這是一個UITableViewCell內的最佳實踐?

關於圖像的下載的最佳做法包括:

  1. 肯定利用自己懶加載(加載圖片,你需要他們,而不是之前)。

  2. 異步下載圖像。

  3. 確保您的下載技術將取消對不再可見的tableview單元格的請求。例如,如果您的網絡速度很慢,並且在桌面視圖中快速向下滾動,則不希望綁定設備下載不再可見的圖像。

  4. 確保您不會對服務器發出太多併發請求。在iOS中,當您超過5個或6個併發請求時,後續請求將凍結,直到先前的請求完成。在最壞的情況下,隨後的請求在超時時會實際開始失敗。

  5. 緩存結果。至少,將它們緩存在內存中。您也可能想將它們緩存到永久存儲器(又名「磁盤」)。

如果你要編寫自己的代碼爲異步操作,緩存等,你可能想使用NSOperationQueue,而不是GCD這樣我就可以限制number of background requests並請求cancelable。您將使用NSCache來緩存圖像。您可能使用UITableViewCell子類(或類別),以便您可以將weak引用保存爲「上一個」操作,以便您可以取消任何不完整的先前請求。你可以看到,這是不平凡的,我建議你使用現有的UIImageView類別,例如作爲SDWebImageAFNetworking的一部分提供的類別。恕我直言,前者有點更豐富(例如提供磁盤緩存),但如果您正在進行大量網絡連接並希望堅持使用單一框架,AFNetworking也可以做得很好。

後來你問:

特別,我應該調整/下載後更換的UIImageView或者我應該調整圖像大小以適合的UIImageView。請注意,調整大小/替換UIImageView也會調整/替換UITableViewCell。它會導致任何問題?

  1. 如果你的圖像比你的細胞的縮略圖視圖需要更大的,你有兩種方法。首先,您可以使用contentModeUIViewContentModeScaleAspectFit or UIViewContentModeScaleAspectFill(如果您使用AspectFill,請確保您也將clipsToBounds設置爲YES)。更好的是,你可以在下載之後使用resize the image

  2. 這是個人意見,但我認爲這是一個更好的UX有固定大小的UIImageView的單元格,然後在異步圖像下載完成後,只需設置UIImageViewimage財產。您希望圖片在下載時能夠優雅地出現在用戶界面中,但您一般不希望在用戶正在閱讀內容的過程中對視圖進行重新佈局。如果您的設計絕對需要重新佈局單元,那麼您可以致電reloadRowsAtIndexPaths

+1

我喜歡你的答案! – Yanchi 2013-06-10 12:33:20

+0

@Yanchi雖然我很欣賞你的支持票,但我必須承認,我後來知道了我近一年前發佈的那個簡單的GCD實施中的重大限制。至少,我會建議'NSOperationQueue'和'NSCache'。更好的是,使用現有的'UIImageView'類(SDWebImage或AFNetworking)來解決我在我的修訂答案中列舉的許多問題。 – Rob 2013-06-10 13:44:56

+0

我試圖使用SDWebImage,但由於缺少一些頭文件而無法編譯,但感謝新的答案! – Yanchi 2013-06-10 14:36:02