Tigran Iskandaryan
Tigran Iskandaryan

Reputation: 1451

Increasing a custom view's height in a table view row (and as a result the row's one, too) programmatically

I have a view (later, referred as custom view) which renders subviews inside of it. After rendering them out, I get a new required height value (so all subviews will be visible) and try to update the height of the view. Here is the code, called from awakeFromNib() method of UITableViewCell's subclass (Note: ReactiveSwift is used in the below code):

customView.model.requiredHeight.producer
        .observe(on: UIScheduler())
        .skipNil()
        .skipRepeats()
        .startWithValues { [weak self] in
            print("increased Height: ", $0)

            self?.customViewHeightConstraint.constant += $0

            print("customView height: ", self?.customView.frame)
    }

So, the correct height to be added to the constraint is grabbed, and the first print statement confirms that. However, this doesn't change view's appearance. The last print statement shows that even I add the value to the view's height constraint, its frame is the same.

I need to mention that this so called custom view is inside a UITableView's row. Here is the layout (the green rect is the cell, the yellow one is a UILabel and the red one is the view):

enter image description here

So, everything is pinned to the edges. I use automatic row height for the row (however, no difference if I set it to custom) and in the table view delegate's tableView(_:estimatedHeightForRowAt:) method return UITableView.automaticDimension as estimated height.

I am sure that I am missing something obvious but can't figure out, honestly. This technique works perfectly if the custom view is not inside a cell, so I think, this has something to do with the table view cell.

Upvotes: 1

Views: 326

Answers (1)

matt
matt

Reputation: 534950

You've done everything right, and your constraints are correct, but the table view has not heard about the fact that they have changed. You need to reload the table view (or at least this row).

The best way to do that, by the way, is by performing an empty batch update, because that will cause the change in constraints to be animated, which is a very nice look.

EDIT: I say "your constraints are correct", but a comment that you later added suggests that this is not true. It sounds like you are trying to "mix and match" fixed layout with autolayout: your custom view uses autolayout, but its subviews do not. Don't do that.

Instead of changing the height constraint of your custom view manually, you should be using constraints internally for all the subviews so that their constraints size the custom view from the inside out — exactly in the same way that the cell itself works. Either that, or you should turn off autoresizing of the cell and implement heightForRowAt to dictate the entire cell height manually.

Upvotes: 1

Related Questions