简体   繁体   中英

Animating a view's height with autolayout when there's no height constraint

I have a view (let's call it "contentView") that its height is determined by its subviews, which is mostly UILabels.

The UILabels content is dynamic and may grow or shrink at runtime. The UILabels have numberOfLines = 0, and no height constraint, which allow their height to grow with the content.

The UILabels have 0 leading/trailing/top/bottom constraints to their neighbors and/or superview, as follows:

在此处输入图片说明

The result is having contentView's height equal the total height of all its sub UILabels (with their height being determined by the height of their text).

I now need to hide contentView on a press of a button (and show it again when the button is pressed again).

Also note, that while animating, if there are other views below "contentView" they need to move in to take the empty space (and move back out when the button is pressed again).

It seems the most natural animation is to change the height of contentView to 0, while animating the views under contentView up at the same time (with the reverse animation changing the height back to its original height).

Any suggestions on how to animate contentView's height?

Unfortunately I was not able to create a smooth enough animation for this layout, but I found a workaround.

Constraints change the layout while animating, and I needed the opposite effect - the layout had to remain fixed while the animation is in progress. So I disabled the constraints for the duration of the animation, and that seemed to work well.

The full recipe is:

I disabled the constraints on contentView:

contentView.translatesAutoresizingMaskIntoConstraints = YES

I then did a simple frame animation. I made sure to calle layoutIfNeeded on superview to make sure the view that's under contentView moves up during the animation:

CGRect frame = view.frame;
frame.size.height = 0;
[[view superview] layoutIfNeeded];
[UIView animateWithDuration:0.5 animations:^{
    view.frame = frame;
    [[view superview] layoutIfNeeded];
}];

I also had to change some properties for the subviews to have them animate correctly (this step might not be needed. It depends to the base layout of the subviews):

for UITextView: scrollEnabled = YES
for UIButton: clipsToBounds = YES

At the end of the animation, on the completion block, I set contentView.translatesAutoresizingMaskIntoConstraints back to NO and restored the subviews properties:

for UITextView: scrollEnabled = NO
for UIButton: clipsToBounds = NO

(I ended up using UITextViews instead of UILabels because I needed the text to be selectable. I then set scrollEnabled to NO to size the textviews based on their content).

Yes: add a height constraint with a constant of 0.

You can use deactivateConstraints() to temporarily disable other constraints that might conflict with this, and activateConstraints() to re-enable them.

You could put the relevant constraints in an array programmatically, or use an outlet collection if you're using a storyboard.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM