Adding and positioning views to UITableViewCell.contentView

Hi there,

the documentation explicitly says this is what's contentView for. I've just tried and found big problems not adding — works like a charm — but positioning my view so that it does not clash with the standard ones.

I've added a small badge at the rightmost edge of contentView. Having added the subview into contentView (in tableView:cellForRowAtIndexPath:, after checking that it does not exist yet in a reused cell view), I set up constraints so that it is Y-centered and sticks to the right edge of the contentView, that was very easy and worked nicely at the first try:

UILayoutGuide *lg=cell.contentView.layoutMarginsGuide;
[badge.trailingAnchor constraintEqualToAnchor:lg.trailingAnchor].active=YES;
[badge.centerYAnchor constraintEqualToAnchor:lg.centerYAnchor].active=YES;

I've found though if the text in textLabel (I have to address iOS12+, thus I can't use content configurations) is long enough, it clashes with the badge instead of clipping/wrapping/whatever it is set to (wrapping in my case).

Thus I've added another constraint which makes sure the trailing edge of textLabel does not exceed the leading edge of my badge:

UILayoutGuide *blg=badge.layoutMarginsGuide;
[cell.textLabel.trailingAnchor constraintLessThanOrEqualToAnchor:blg.leadingAnchor constant:-6].active=YES;

Oops: that pushed the badge right, so that it overlaps the accessory area.

By my further testing, seems the culprit is another constraint (probably created dynamically later from the autoresizing mask) which bounds the right edge of textLabel to the right edge of contentView. I've tried to find and remove (deactivate) it in tableView:cellForRowAtIndexPath:, in vain, well, makes some sense perhaps, too soon. I've tried to find and remove it in tableView:willDisplayCell:forRowAtIndexPath:; no luck either. To me, this does not make sense at all.

(It sort of looks like the documentation claim “After the delegate returns, the table view sets only the alpha and frame properties, and then only when animating rows as they slide in or out” is highly overstated. Self-evidently, non-trivial layout stuff happens after the delegate returns, but before the cell is drawn.)

Eventually, having used updateConstraints explicitly (which does not feel right), I succeeded to find the darn thing, a fixed width constraint for textLabel. Tried to deactivate it: does not work, setting its active property to NO does nothing, no warning, no error, no exception, thing just stays at YES. I've tried to decrease its priority, that's even more funny: it goes down, when checked, it is down, but 1000 is somehow re-surrected after tableView:willDisplayCell:forRowAtIndexPath: returns, but before the cell is finally laid out and drawn. Ick.

What's the proper solution of this? I suppose it should be pretty easy, but it is not, or I must be overlooking something pretty obvious. Thanks!