【问题标题】:Adding new (non-reusable) cells for every row in UItableview swift为 UItableview swift 中的每一行添加新的(不可重用的)单元格
【发布时间】:2016-11-29 16:08:29
【问题描述】:

UITableView 的大部分单元格中都有UIWebView,用于显示视频。
在大多数情况下,单元格的数量会更少,但这些可能是无穷无尽的。滚动UITableView; webView 每次都会重新加载其数据。

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


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

【问题讨论】:

  • 您能否展示您的 cellForRowAtIndexPath,以便我可以轻松地向您展示如何解决您的问题。

标签: ios iphone swift uitableview ios9


【解决方案1】:

您可以创建以 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()
}

如果您有很多单元格,您可能会遇到内存问题。

【讨论】:

    【解决方案2】:

    如果考虑效率和性能,你必须重用单元格并重新加载单元格中的webview,只需重新加载从未播放过的,同时将视频数据或html数据缓存到本地。另一方面,对于播放单元格,您可以记录 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];
    }
    

    希望我的回答对你有用。

    更新:

    使用 Swift 的伪代码:

    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)
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-03-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-04-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多