为什么UILabel的边界上的animation只有在增大尺寸时才起作用?

我注意到,当我改变一个animation块中的UILabel的边界,它只能工作,如果我增加的大小,当我减less大小的UILabel只是改变他的大小,但不animation。 用一个普通的UIViewreplaceUILabel按预期工作。

注意:将UILabel的contentMode属性更改为UIViewContentModeScaleToFill可修复此问题,但我仍然不明白为什么它在不更改contentMode属性的情况下增加大小时会起作用。

#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 

这是因为UILabel将其图层的contentsGravity UILabel设置为正在呈现的方向文本,这恰好默认为UIViewContentModeLeft (或@"left" )。 因此,当图层被告知要进行animation处理时,首先要看一看它的内容重力,然后根据后续animation制作animation。 因为它看到@"left" ,那里应该有@"resize" ,它假设缩放animation应该从左边开始,但是它也必须尊重你给出的约束(边界改变),所以你的标签似乎跳到最后的大小,然后定居在屏幕的中心位置。

如果您想单独保留contentMode ,请使用CATransform3D ,然后按照这种方式缩放标签的图层,而不是更改边界。