【发布时间】:2015-08-06 09:57:38
【问题描述】:
我的 UITableView 带有动态调整大小的单元格,它以 HTML 格式显示 cmets 列表,我遇到了 NSAttributedString 呈现 HTML 内容非常慢的问题!
这是来自分析器的快照。
我尝试将 NSAttributedString 初始化放到单独的线程中,但仍然很慢,并且用户在呈现 HTML 时会看到空单元格,最后在完成渲染时单元格布局不正确。
dispatch_async(GlobalQueue, {
let html = NSAttributedString(
data: self.comment.htmlBody.dataUsingEncoding(NSUnicodeStringEncoding, allowLossyConversion: false)!,
options: [NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType],
documentAttributes: nil,
error: nil)
dispatch_async(MainQueue, {
self.commentLabel.attributedText = html
self.commentLabel.font = UIFont(name: "HelveticaNeue-Light", size: 14.0)!
if let writer = self.comment.author {
self.authorLabel.text = writer.name
}
self.layoutIfNeeded()
})
})
请建议如何加快渲染和修复单元格布局。
谢谢!
更新:
解决了单元格委托和标志,表明属性字符串已初始化。也许会帮助某人:
// TicketCell
private var isContentInitialized = false
private var commentAttributedString:NSAttributedString?
var delegate: TicketCommentCellDelegate?
var indexPath: NSIndexPath!
var comment: TicketComment! {
willSet {
if newValue != self.comment {
self.isContentInitialized = false
}
}
didSet{
self.configure()
}
}
...
private func configure() {
if isContentInitialized {
// here might be activity indicator stop
...
if let writer = self.comment.author {
self.authorLabel.text = writer.name
}
}
else {
// here might be activity indicator start
dispatch_async(GlobalQueue, {
self.commentAttributedString = NSAttributedString(
data: self.comment.htmlBody.dataUsingEncoding(NSUnicodeStringEncoding, allowLossyConversion: false)!,
options: [NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType],
documentAttributes: nil,
error: nil)
self.isContentInitialized = true
// here might be spinner stop
dispatch_async(MainQueue, {
self.delegate?.ticketCommentCellDidRenderCommentHTML(self)
})
})
}
}
...
protocol TicketCommentCellDelegate {
func ticketCommentCellDidRenderCommentHTML(cell: TicketCommentCell)
}
// TableViewDataSource
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier(kTicketCommentCellIdentifier, forIndexPath: indexPath) as! TicketCommentCell
cell.indexPath = indexPath
cell.delegate = self
cell.comment = self.rows[indexPath.section][indexPath.row]
return cell
}
// MARK: - TicketCommentCellDelegate
func ticketCommentCellDidRenderCommentHTML(cell: TicketCommentCell) {
self.tableView.reloadRowsAtIndexPaths([cell.indexPath], withRowAnimation: UITableViewRowAnimation.Automatic)
}
// MARK: UITableViewDelegate
func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
var cell = self.commentCell
cell.comment = self.rows[indexPath.section][indexPath.row]
cell.setNeedsDisplay()
cell.setNeedsLayout()
let height = cell.contentView.systemLayoutSizeFittingSize(UILayoutFittingCompressedSize).height + 1
return height
}
【问题讨论】:
-
你的内容有多大?
-
不大,简单的邮件模板,一句话,一个段落的签名,还有几个href链接。约 1000 个字符
-
没有从其他来源加载其他外部资源,例如 CSS 或 JavaScript?
-
谢谢大家,解决了。更新了代码示例
-
顺便说一句。模拟器解析 HTML 到 NSAttributedString 比实际设备慢很多,你可以自己试试
标签: ios swift uitableview grand-central-dispatch nsattributedstring