Почему анимации на границах UILabel работают только при увеличении размера?
Я заметил, что когда я изменяю границы UILabel в блоке анимации, он работает только, если я увеличиваю размер, когда я уменьшаю размер, UILabel просто меняет свой размер, но не оживляет.
Замена UILabel на простой UIView работает по назначению.
Примечание. Изменение свойства contentMode UILabel на 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
Ответы
Ответ 1
Это потому, что UILabel
устанавливает свой слой contentsGravity
в текстовый текст направления, который по умолчанию имеет значение UIViewContentModeLeft
(или @"left"
). Таким образом, когда слой сообщается анимации, он сначала рассматривает его содержимое гравитации и основывает на нем последующие анимации. Поскольку он видит @"left"
, где должен быть @"resize"
, он предполагает, что анимация масштабирования должна начинаться слева, но она также должна учитывать ограничения, которые вы ей дали (изменения границ), поэтому ваша метка появляется прыгайте в его окончательный размер, затем оседайте там, где он должен находиться в центре экрана.
Если вы хотите оставить только contentMode
, используйте CATransform3D
и масштабируйте слой метки таким образом вместо изменения границ.