为UItableview中的每一行添加新的(不可重用的)单元格swift
问题描述:
我在UITableView
的大部分单元格中都有UIWebView
,它们用于显示视频。
在大多数情况下,细胞数量会少一些,但这些可能是无止境的。在滚动UITableView
; webView每次都会重新载入其数据。为UItableview中的每一行添加新的(不可重用的)单元格swift
任何人都可以有解决方案如何为每行创建新单元而不是使用dequeueReusableCellWithIdentifier以防止在UIWebView中重新加载。
我还是不喜欢每次都创建新的单元格。
但是然后如何防止每次重新加载webView?
答
您可以创建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
你能告诉你的cellForRowAtIndexPath,所以我可以很容易地告诉你如何解决您的问题。 – pnizzle