簡體   English   中英

目標C UITableView無法與自定義單元格和視圖平滑滾動

[英]objective c UITableView not scrolling smooth with custom cell & views

我希望tableview在每一行中顯示可滾動的多個圖像。 為此,我使用UITableViewCustom UITableViewCell ,在自定義tableView單元格中,我正在生成具有多個視圖和圖像的滾動視圖,因此,當我滾動表格時,其滾動不會平穩地閃爍。 誰能建議我以更好的方式做到這一點?

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 
   // Products table view. 
   ProductCustomCell *cell = (ProductCustomCell *)[tableView dequeueReusableCellWithIdentifier:@"CatelogCell"] ;//] forIndexPath:indexPath]; 
   if (cell == nil) { 
      cell = [[ProductCustomCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"CatelogCell"]; 
   } 
   cell.productCellDelegate = self; 
   [cell initProperties]; 
   [cell showProductsInScroll:catelogBundle];
}

如果要平滑地滾動tableview,則應注意一些技巧。

  1. 緩存行的高度(表視圖可以經常請求),實際上,這並不是阻止表視圖滾動的關鍵點。

  2. 為表中使用的圖像創建最近最少使用的緩存(並在收到內存警告時使所有不活動的條目無效)-您可以使用SDWebImage下載圖像並緩存它們。 有時,您可能想要緩存一些經常用於表視圖的圖像,即使當前視圖為頂視圖,即使您收到內存警告,這些圖像也可能無法釋放。

  3. UITableViewCelldrawRect:繪制所有內容drawRect:如果可能,不惜一切代價避免使用子視圖(或者,如果您需要標准的可訪問性功能,則使用內容視圖的drawRect: )-可以節省一些成本,但也可能花費更多的時間來編寫代碼也許很難維護代碼。 但是,在uitableviewcell上使用較少的視圖確實很好,這將改善您的性能。

  4. 使UITableViewCell的圖層不透明(如果有的話,對內容視圖也一樣)-請盡可能少使用圖層不透明。

  5. 使用UITableView示例/文檔推薦的reusableCellIdentifier功能-您必須遵循此提示。

  6. 避免未預先烘焙到UIImage的漸變/復雜的圖形效果-如第4點。

當然,大多數時候,如果您的表格視圖滾動不平滑,則主要問題是您要同步加載圖像。

使用儀器測試性能真的很好。

您可能已經為您的問題找到了解決方案,但是如果您仍在尋找,這對我很有用。 我還在開發一個應用程序,該應用程序需要在多個tableview單元格上顯示許多圖片。

我發現,每次應用程序將一個新的單元cellForRowAtIndexPath載到尚未顯示​​的屏幕上時,就會調用cellForRowAtIndexPath方法,因此,每次向上或向下滾動到新單元格時,即使某些滾動到其他位置之前,屏幕上的單元格已顯示在屏幕上。

我所做的是將第一次初始化的單元格及其對應的索引路徑保存到數組中,並再次調用cellForRowAtIndexPath方法時,通過檢查索引路徑是否存儲在我的索引路徑數組中來檢查此單元格是否已初始化。

@implementation MyViewController{
    NSMutableArray *cells;
    NSMutableArray *indexpaths;
}

...

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{

    // check if in array
    if ([indexpaths containsObject:indexPath]){
        return cells[indexPath.row];
    }

    // otherwise, create a new one
    UITableViewCell *cell = [[UITableViewCell alloc] init];

    // customizing cell
    // other stuff
    ...

    // finally save the cell and indepath for checking later
    [cells addObject:cell];
    [indexpaths addObject:indexPath];

    return cell;
}

我認為問題可能是您可能在UITableView的cellForRowAtIndexPath委托方法中分配對象。 因此,與其分配任何類型的對象,不如在其ProductCustomCell類中分配或在其xib文件中創建它。

除了TinyMonk的答案,我想添加一個簡單的方法。 如果使用自定義單元格制作uitableview,請確保在表和自定義單元格上都選中clip subview選項。 它為我工作。

基於Leo C han的解決方案,我已將其更新為Swift3。

var manualCells = NSMutableArray()

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

   // check if in array
   if manualCells.contains(indexPath) {
      return manualCells.object(at: indexPath.row) as! UITableViewCell
   }

   let cell = self.tableViewReference.dequeueReusableCell(withIdentifier: "mainIdentifier") as! YourTableViewCell

   // fill the cell...     

   manualCells.insert(cell, at: indexPath.row)
   return cell
}

注意,這是針對包含一個部分的表的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM