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?