Autolayout动画约束不会为子视图设置动画

时间:2013-11-20 13:41:55

标签: ios objective-c animation constraints autolayout

我有一个UIView,它有一个UILabel作为子视图。

现在我用动画更改UIView的宽度(更改约束的常量属性)并在UIView动画中调用layoutIfNeeded ......)

视图正在调整正常大小, UILabel(子视图)将字体大小更改为'end'大小,但没有像uiview那样正确设置动画。

根据WWDC 2012会议,只有超级视图的常量发生变化时,子视图才会生成动画。

UILabel的最小字体比例为0,1,小于字体必须调整大小。

2 个答案:

答案 0 :(得分:4)

通过更改UILabel约束,我正在努力为width调整大小设置动画效果。标签设置了adjustsFontSizeToFitWidthminimumScaleFactor

我通过将标签“contentMode设置为UIViewContentModeScaleAspectFit来修复它。标签默认为UIViewContentModeLeft

答案 1 :(得分:2)

我认为你不能通过这种方式设置文本的大小。我能想到的唯一方法是创建标签的快照视图,在标签上添加该视图,执行动画,然后删除快照视图。此代码确实将较小的文本略微向下移动,但它看起来非常好,当您取消隐藏标签并删除图像视图时,只有非常小的移动。包含标签的小视图大小为185x36,标签在smallView的每一边都有20的约束,8到顶部,7到底部。我在代码中将相同的约束添加到图像视图中。

@interface ViewController ()
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *widthCon; // width constraint on smallView
@property (weak,nonatomic) IBOutlet UIView *smallView; // view that the label is embedded in
@property (weak,nonatomic) IBOutlet UILabel *label;
@end

@implementation ViewController

- (IBAction)shrinkView:(id)sender {

    UIView *snapshot = [self.label snapshotViewAfterScreenUpdates:YES];
    [snapshot setTranslatesAutoresizingMaskIntoConstraints:NO];
    [self.smallView addSubview:snapshot];
    [self.smallView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"|-20-[snapshot]-20-|" options:0 metrics:nil views:@{@"snapshot":snapshot}]];
    NSLayoutConstraint *topCon = [NSLayoutConstraint constraintWithItem:snapshot attribute:NSLayoutAttributeTop relatedBy:0 toItem:self.smallView attribute:NSLayoutAttributeTop multiplier:1 constant:8];
    NSLayoutConstraint *bottomCon = [NSLayoutConstraint constraintWithItem:self.smallView attribute:NSLayoutAttributeBottom relatedBy:0 toItem:snapshot attribute:NSLayoutAttributeBottom multiplier:1 constant:7];
    [self.smallView addConstraints:@[topCon,bottomCon]];
    [self.smallView layoutSubviews];
    self.label.alpha = 0;
    self.widthCon.constant = 100;
    topCon.constant = 18;
    bottomCon.constant = 10;
    [UIView animateWithDuration:.5 animations:^{
            [self.view layoutIfNeeded];
        } completion:^(BOOL finished) {
            self.label.alpha = 1;
            [snapshot removeFromSuperview];
        }];
}

编辑后:

有一种方法可以为视图设置动画,以便标签也可以向下设置动画,而不是立即转到最终尺寸。您必须使用计时器直接为约束设置动画(请参阅WWDC 2012视频大约31分钟的说明,“掌握自动布局的最佳实践”)。这可以设置标签大小的动画,但字体大小更改是跳跃的,并且看起来不那么好。如果您对标签所在的视图有宽度约束(并且标签对双方有约束),那么您可以这样做:

-(IBAction)animateSizeChange:(id)sender {
    [NSTimer scheduledTimerWithTimeInterval:.001 target:self selector:@selector(doStuff:) userInfo:Nil repeats:YES];
}

-(void)doStuff:(NSTimer *) aTimer {
    self.widthCon.constant -= .2;
    if (self.widthCon.constant <90) [aTimer invalidate];
}