Within the UITableView datasource, I convert an HTML string to NSAttributedString and set it on a label in the cell using the following routine,
class MyCell: UITableViewCell {
private let bodyLabel = UILabel()
private var _bodyText = ""
private var _viewModel = MyCellViewModel()
var bodyText: String {
set {
_bodyText = newValue
let modifiedFont = String(format:"<span style=\"font-family: '\(Fonts.plexSans)', '\(Fonts.plexSans)'; font-size: 18\">%@</span>", newValue)
let attrStr = try! NSAttributedString(
data: modifiedFont.data(using: .utf8, allowLossyConversion: false)!,
options: [.documentType: NSAttributedString.DocumentType.html,
.characterEncoding:String.Encoding.utf8.rawValue],
documentAttributes: nil)
bodyLabel.attributedText = attrStr
}
get {
return _bodyText
}
}
var viewModel: MyCellViewModel {
set {
_viewModel = newValue
bodyText = newValue.body
}
get {
return _viewModel
}
}
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
// does a bunch of straightforward layout constraints etc.
}
}
extension MyViewController: UITableViewDataSource {
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cellViewModel = modelForIndexPath(indexPath)
let cell = tableView.dequeueReusableCell(withIdentifier: MyCell.Name, for: indexPath) as! MyCell
cell.viewModel = cellViewModel
return cell
}
This sometimes causes the UITableView to become unstable. Generating an error in the console, Error is "Assert UITableView internal inconsistency prefetchedCells and indexPathsForPrefetchedCells are out of sync
.
Sometimes this appeared as a row duplicated, partially drawn row, crash with index out of range.
Found a similar issue in Stackoverflow
HTML strings are simple strings only supporting <br>
and <b>
tags within text. HTML is short.
The solution presented there worked. I moved the conversion from HTML to NSAttributedString to an earlier step where I'm creating the data for the tableview and moved it out of cellForRowAt..
datasource method.
Why is this a fix? Why would this conversion cause an issue while filling out a UITableViewCell?