У меня есть UITableView с динамическими ячейками размера, который отображает список комментариев в формате HTML, и я столкнулся с проблемой, что NSAttributedString делает HTML-контент чрезвычайно медленным!Очень медленный рендеринг HTML в NSAttributedString
Это снимок от профилировщика.
Я пытался поставить инициализацию 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
}
, как большой ваш контент? – holex
Не большой, простой шаблон электронной почты, одно предложение, подпись об одном абзаце с несколькими ссылками href. Около 1000 символов – Madman
другие внешние ресурсы не загружаются из какого-либо другого источника, например _CSS_ или _JavaScript_? – holex