【问题标题】:Animating Constraint Changes, position animates but height jumps without animation动画约束变化,位置动画,但高度跳跃没有动画
【发布时间】:2014-07-08 05:54:08
【问题描述】:

我有一个自定义 UIView。在该 UIView 中,我有一个黄色背景的 UILabel,其中包含 @"8",名为 labelWhite。我以编程方式为该 UILabel 创建了 4 个约束:顶部、左侧、宽度和高度。

当我点击 UIView 时,我会更改高度的常量值并在 5 秒内为布局设置动画。但是,视图的高度会立即跳转到新值,但是 y 位置也会发生变化并立即跳转到新值。然后在 5 秒的动画中,y 位置动画回到它应该一直停留的位置。

你可以在这里看到它的视频:http://inadaydevelopment.com/stackoverflow/Constraints0.mov

它应该做的只是保持 y=0 并垂直收缩。我做错了什么?


编辑:

我刚刚发现,如果我的子视图是 UIView,我的动画效果完全符合预期,但作为 UILabels,我得到了 jump-size + animate-position。

发生了什么事?有没有办法让 UILabel 为其大小设置动画?


这是我用来修改和动画布局的代码:

self.constraintWhiteHeight.constant = secondaryHeight;

[UIView animateWithDuration:5.0 animations:^{
    [self layoutIfNeeded];
}];

这是我用来创建约束的代码:

// ------ Top -----
NSLayoutConstraint *constraint = [NSLayoutConstraint constraintWithItem:self
                                                              attribute:NSLayoutAttributeTop
                                                              relatedBy:NSLayoutRelationEqual
                                                                 toItem:self.labelWhite
                                                              attribute:NSLayoutAttributeTop
                                                             multiplier:1.0
                                                               constant:0];
[self addConstraint:constraint];

// ------ Left -----
self.constraintWhiteLeft = [NSLayoutConstraint constraintWithItem:self
                                                        attribute:NSLayoutAttributeLeft
                                                        relatedBy:NSLayoutRelationEqual
                                                           toItem:self.labelWhite
                                                        attribute:NSLayoutAttributeLeft
                                                       multiplier:1.0
                                                         constant:0];

// ------ Width -----
NSString *constraintString = [NSString stringWithFormat:@"H:[_labelWhite(==%.0f)]", self.bounds.size.width];
NSArray *constraints = [NSLayoutConstraint constraintsWithVisualFormat:constraintString
                                                               options:0
                                                               metrics:nil
                                                                 views:NSDictionaryOfVariableBindings(_labelWhite)];
NSLog(@"constraints: %@", constraints);
self.constraintWhiteWidth = [constraints objectAtIndex:0];
[self.labelWhite addConstraints:constraints];

// ------ Height -----
constraintString = [NSString stringWithFormat:@"V:[_labelWhite(==%.0f)]", primaryHeight];
constraints = [NSLayoutConstraint constraintsWithVisualFormat:constraintString
                                                      options:0
                                                      metrics:nil
                                                        views:NSDictionaryOfVariableBindings(_labelWhite)];
self.constraintWhiteHeight = [constraints objectAtIndex:0];
[self.labelWhite addConstraints:constraints];

【问题讨论】:

    标签: ios ios7 nslayoutconstraint


    【解决方案1】:

    我认为您没有做错任何事情,这似乎是标签在您尝试为其高度设置动画时的行为方式。我知道我过去曾遇到过这个问题,但我不记得我是否曾经找到通过动画块中的约束动画来工作的解决方案。我让它工作的方法是使用计时器或 CADisplayLink 来调整高度约束。

    -(void)shrinkLabel {
        self.constraintWhiteHeight.constant -= 1;
        if (self.constraintWhiteHeight.constant >= secondaryHeight)
        [self performSelector:@selector(shrinkLabel) withObject:nil afterDelay:.05];
    }
    

    编辑后:

    虽然计时器方法有效,但它并不总是看起来很流畅,具体取决于您使用的速度和增量。另一种方法是使用一个较大的 UIView(与电影中的黄色标签大小相同)和一个较小的 UILabel,其中对较大的视图具有 centerX 和 centerY 约束。然后,像往常一样使用 animateWithDuration:animations: 为黄色视图设置动画:

    -(void)shrinkLabel {
        self.yellowViewHeightCon.constant = secondaryHeight;
        [UIView animateWithDuration:5 animations:^{
            [self layoutIfNeeded];
        }];
    }
    

    【讨论】:

    • 解决这个问题的有趣方式。谢谢,我会玩一下。
    • 第二种,layoutIfNeeded 方法是我在问题中使用的方式。它适用于 UIVIews,但 UILabel 的绘制方式不同,并且不适用于这些。
    • @KennyWyland,但它确实适用于我在编辑中显示的设置,我正在制作动画的是外部(黄色)UIView,并且较小的标签在视图缩小时保持正确居中。这不是你想要的吗?
    • 外部视图将保持相同大小,但内部视图将移动并更改大小。当它改变大小时,我希望它的内容(“8”)随之改变大小。问题是 UILabel 在大小动画期间不会更改文本的大小,因此它会跳转到新的 end-size-font 然后动画到所需的大小。
    • @KennyWyland,好吧,这不是你在电影中显示的内容,文本在那里保持相同大小,所以这就是我认为你想要的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-26
    • 1970-01-01
    • 2012-03-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多