为UItableview中的每一行添加新的(不可重用的)单元格swift

问题描述:

我在UITableView的大部分单元格中都有UIWebView,它们用于显示视频。
在大多数情况下,细胞数量会少一些,但这些可能是无止境的。在滚动UITableView; webView每次都会重新载入其数据。为UItableview中的每一行添加新的(不可重用的)单元格swift

任何人都可以有解决方案如何为每行创建新单元而不是使用dequeueReusableCellWithIdentifier以防止在UIWebView中重新加载。


我还是不喜欢每次都创建新的单元格。
但是然后如何防止每次重新加载webView?

+0

你能告诉你的cellForRowAtIndexPath,所以我可以很容易地告诉你如何解决您的问题。 – pnizzle

您可以创建NSIndexPath字典作为键和UITableViewCell的作为价值

// MARK: - Properties 

private var cells: [NSIndexPath: VideoCell] = [:] 
private var videos: [Video] = [] 

// MARK: - UITableViewDataSource 

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { 
    if let cachedCell = self.cells[indexPath] { 
     return cachedCell 
    } 
    else { 
      let videoCell = tableView.dequeueReusableCellWithIdentifier(VideoCell.ReuseIdentifier, forIndexPath: indexPath) as! VideoCell 
      videoCell.bindWith(self.videos[indexPath]) 
      self.cells[indexPath] = videoCell 
      return videoCell 
     } 
    } 

// MARK: - UITableViewDelegate 

func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) { 
    guard let videoCell = cell as? VideoCell else { 
     return 
    } 
    videoCell.refresh() 
} 

如果你将有很多细胞的可能与内存问题朝上。

如果您考虑效率和性能,只需重新加载从未播放过的视频,并且同时将视频数据或html数据缓存到本地,则必须重用该单元并重新加载单元格中的web视图。另一方面,对于播放单元格,您可以记录webview的对象,直接将这些webviews设置为重用单元格。

伪代码:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 
    YourCell *cell = [tableView dequeueReusableCellWithIdentifier:@"CellIdentifier" forIndexPath:indexPath]; 
    // If the video at this row is playing, just setup webview 
    UIWebView *webView = [self webviewOfPalyingForIndexPath: indexPath]; 
    if (webView) { 
     [cell setupWithWebview: webView]; 
    } else { 
     // Configure cell with reused webview 
     static UIWebView *publicWebview = [UIWebView new]; 
     [cell setupWithWebview: publicWebview]; 

     // Check if the data of webview is cached 
     NSData *cachedData = [self readCachedDataForIndexPath: indexPath]; 
     if (cachedData) { 
      [cell setupWithCachedData:cachedData]; 
     } else { // If not cached, load url and cach the data 
      [cell setupWithUrl: your_url]; 
      [self cacheDataForUrl: your_url]; 
     } 
    } 
    return cell; 
} 

// Record webview of playing at indexPath 
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { 
    YourCell *cell = (YourCell *)[tableView cellForRowAtIndexPath:indexPath]; 
    [self recordPlayingWebView: cell.webview atIndexPath: indexPath]; 
} 

希望我的回答对你有用。

UPDATE:

与伪银行代码:

let reusedWebview = UIWebView() 
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { 
    let cell = tableView.dequeueReusableCellWithIdentifier("CellIdentifier", forIndexPath: indexPath) 
    // If the video at this row is playing, just setup webview 
    let webView = self.webviewOfPalyingForIndexPath(indexPath) 
    if (webView != nil) { 
     cell.setupWithWebview(webView) 
    } else { 
     // Configure cell with reused webview 
     cell.setupWithWebview(resuedWebview) 

     // Check if the data of webview is cached 
     let cachedData = self.readCachedDataForIndexPath(indexPath) 
     if (cachedData != nil) { 
      cell.setupWithCachedData(cachedData) 
     } else { // If not cached, load url and cach the data 
      cell.setupWithUrl(your_url) 
      self.cacheDataForUrl(your_url) 
     } 
    } 
    return cell; 
} 

func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) { 
    let cell = tableView.cellForRowAtIndexPath(indexPath) 
    self.recordPlayingWebView(cell.webview, forIndexPath: indexpath) 
} 
+1

@EricD谢谢,更新了答案。 – Yahoho