dequeued UITableViewCell has incorrect layout until scroll (using autolayout)
If you name a property on a UITableViewCell
subclass textLabel
or defaultTextLabel
, then IB will ignore the constraints you have specified and override them with default ones, with no warnings issued.
This is the case even on cells designed in IB with the Custom style, which have no visible textLabel
or detailTextLabel
properties.
This also happen if add a property of type UIImageView
property on a UITableViewCell
subclass and name it imageView
.
In accordance to this multiple lines UILabel
GitHub issue, this is a lingering iOS bug.
I found that in iOS 9+, this situation mostly occurs in editing mode, with much unpredictability.
The following workaround only partially works: it requires redrawing the UITableView
twice, and still does not cover all scenarios.
override func viewDidLoad() { super.viewDidLoad() tableView.setNeedsLayout() tableView.layoutIfNeeded() tableView.reloadData()}
Notes:
- Using
UITextView
is a great alternative to multiple lineUILabel
, without the bug.UITextView
does not exhibit any of theIULabel
other oddities either, like alignment errors or flickering. - There is also an alternative solution on SO-25947146, which did not work for me but is worth mentioning.
- Seems to occur prominently when
self.tableView.editing
istrue
- Using low values for
tableView.estimatedRowHeight
reduces the occurrence - Demonstration of the bug on SwiftArchitect/TableViewControllerRowHeightBug gist
In my case, I call method tableView.reloadData() in viewDidAppear and the layout appear correctly
override func viewDidAppear(_ animated: Bool) { super.viewDidAppear(animated) self.tableView.reloadData()}