Why are animations on bounds of an UILabel only working when increasing the size?

爷,独闯天下 提交于 2019-11-27 05:42:44

问题


I noticed that when i change the bounds of an UILabel in an animation block it only works if i increase the size, when i decrease the size the UILabel just changes his size but doesn't animate. Replacing the UILabel with a plain UIView works as intended.

Note: Changing the contentMode property of the UILabel to UIViewContentModeScaleToFill fixes this issue, but i still don't understand why it works when increasing the size without changing the contentMode property.

#import "FooView.h"

@interface FooView ()
@property (strong, nonatomic) UILabel   *label;
@property (assign, nonatomic) BOOL       resized;
@end

@implementation FooView

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        self.backgroundColor = [UIColor lightGrayColor];

        self.label = [[UILabel alloc] initWithFrame:(CGRect){0, 0, frame.size}];
        self.label.backgroundColor = [UIColor greenColor];
        [self addSubview:self.label];
        _resized = false;

        UITapGestureRecognizer *tapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(changeSize)];
        tapRecognizer.numberOfTapsRequired = 1;
        [self addGestureRecognizer:tapRecognizer];
    }
    return self;
}

- (void)changeSize {
    [UIView animateWithDuration:0.8
                          delay:0.0
                        options:UIViewAnimationOptionCurveEaseIn
                     animations:^{
                         CGRect bounds = self.label.bounds;
                         if (self.resized) {
                             bounds.size.height *= 2;
                             bounds.size.width  *= 2;
                         } else {
                             bounds.size.width  /= 2;
                             bounds.size.height /= 2;
                         }
                         self.label.bounds = bounds;
                     }
                     completion:^(BOOL finished) {
                         self.resized = !self.resized;
                     }];
}

@end

回答1:


It's because UILabel sets its layer's contentsGravity to the direction text is being rendered, which happens to default to UIViewContentModeLeft (or @"left"). Thus, when the layer is told to animate, it first takes a glance at its contents gravity and bases subsequent animations on that. Because it sees @"left" where there should be @"resize", it assumes that the scaling animation should begin from the left, but it also has to respect the constraints you've given it (the bounds changes), so your label appears to jump into its final size then settle where it should in the center of the screen.

If you want to leave contentMode alone, use CATransform3D's and scale the label's layer that way instead of a bounds change.



来源:https://stackoverflow.com/questions/17360402/why-are-animations-on-bounds-of-an-uilabel-only-working-when-increasing-the-size

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!